中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

有沒(méi)有做網(wǎng)站的教程網(wǎng)站收錄查詢代碼

有沒(méi)有做網(wǎng)站的教程,網(wǎng)站收錄查詢代碼,深圳建設(shè)工程質(zhì)量檢測(cè)中心,如何在百度上推廣自己目錄 1 拿到一個(gè)功能模塊首先需要拆分組件: 2 使用組件實(shí)現(xiàn)靜態(tài)頁(yè)面的效果 3 分析數(shù)據(jù)保存在哪個(gè)組件 4 實(shí)現(xiàn)添加數(shù)據(jù) 5 實(shí)現(xiàn)復(fù)選框勾選 6 實(shí)現(xiàn)數(shù)據(jù)的刪除 7 實(shí)現(xiàn)底部組件中數(shù)據(jù)的統(tǒng)計(jì) 8 實(shí)現(xiàn)勾選全部的小復(fù)選框來(lái)實(shí)現(xiàn)大復(fù)選框的勾選 9 實(shí)現(xiàn)勾選大復(fù)選框來(lái)…

目錄

1 拿到一個(gè)功能模塊首先需要拆分組件:

2 使用組件實(shí)現(xiàn)靜態(tài)頁(yè)面的效果

3 分析數(shù)據(jù)保存在哪個(gè)組件

4 實(shí)現(xiàn)添加數(shù)據(jù)

5 實(shí)現(xiàn)復(fù)選框勾選

6 實(shí)現(xiàn)數(shù)據(jù)的刪除

7 實(shí)現(xiàn)底部組件中數(shù)據(jù)的統(tǒng)計(jì)

8 實(shí)現(xiàn)勾選全部的小復(fù)選框來(lái)實(shí)現(xiàn)大復(fù)選框的勾選

9 實(shí)現(xiàn)勾選大復(fù)選框來(lái)實(shí)現(xiàn)所有的小復(fù)選框都被勾選

10 清空所有數(shù)據(jù)

11 實(shí)現(xiàn)案例中的數(shù)據(jù)存入本地存儲(chǔ)

12 案例中使用自定義事件完成組件間的數(shù)據(jù)通信

13 案例中實(shí)現(xiàn)數(shù)據(jù)的編輯

14 實(shí)現(xiàn)數(shù)據(jù)進(jìn)出的動(dòng)畫(huà)效果


【分析】組件化編碼的流程

1. 實(shí)現(xiàn)靜態(tài)組件:抽取組件,使用組件實(shí)現(xiàn)靜態(tài)頁(yè)面效果

2.展示動(dòng)態(tài)數(shù)據(jù):

? ? ? ? 2.1 數(shù)據(jù)的類(lèi)型、名稱是什么?

? ? ? ? 2.2 數(shù)據(jù)保存在哪個(gè)組件?

3.交互---從綁定事件監(jiān)聽(tīng)開(kāi)始


1 拿到一個(gè)功能模塊首先需要拆分組件:


2 使用組件實(shí)現(xiàn)靜態(tài)頁(yè)面的效果

【main.js】

import Vue from 'vue'
import App from './App.vue'Vue.config.productionTip = falsenew Vue({el: '#app',render: h => h(App)
})

【MyHeader】

<template><div class="todo-header"><input type="text"/></div>
</template><script>export default {name: 'MyHeader',}
</script><style scoped>/*header*/.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;}.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);}
</style>

【Item】

<template> <li><label><input type="checkbox"/><span v-for="todo in todos" :key="todo.id">{{todo.title}}</span></label><button class="btn btn-danger">刪除</button></li>
</template><script>export default {name: 'Item',data() {return {todos: [{id: '001', title: '吃飯', done: true},{id: '002', title: '學(xué)習(xí)', done: false},{id: '003', title: '追劇', done: true},]}},}
</script><style scoped>/*item*/li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;}li label {float: left;cursor: pointer;}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;}li button {float: right;display: none;margin-top: 3px;}li:before {content: initial;}li:last-child {border-bottom: none;}li:hover {background-color: rgb(196, 195, 195);}li:hover button{display: block;}
</style>

【List】

<template><ul class="todo-main"><Item></Item><Item></Item></ul>
</template><script>import Item from './Item.vue'export default {name: 'List',components:{Item},}
</script><style scoped>/*main*/.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;}
</style>

【MyFooter】

<template><div class="todo-footer"><label><input type="checkbox"/></label><span><span>已完成 0</span> / 3</span><button class="btn btn-danger">清除已完成任務(wù)</button></div>
</template><script>export default {name: 'MyFooter',}
</script><style scoped>/*footer*/.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}
</style>

【App】?

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader></MyHeader><List></List><MyFooter></MyFooter></div></div></div>
</template><script>import MyHeader from './components/MyHeader.vue'import List from './components/List.vue'import MyFooter from './components/MyFooter.vue'export default {name:'App',components:{MyHeader,List,MyFooter} }
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>

通過(guò)以上代碼就可以實(shí)現(xiàn)靜態(tài)頁(yè)面的效果了!!!

3 分析數(shù)據(jù)保存在哪個(gè)組件

在上述代碼中數(shù)據(jù)是保存在Item組件中的,但是如果想要在后續(xù)實(shí)現(xiàn)一系列交互效果:在MyHeader組件中需要添加數(shù)據(jù),而MyHeader組件和Item組件沒(méi)有直接的關(guān)系, 就當(dāng)前學(xué)習(xí)階段的知識(shí)而言,并不能實(shí)現(xiàn)這兩個(gè)組件之間的通信(后續(xù)會(huì)有解決方案),同理MyFooter也一樣。


【分析】因?yàn)锳pp組件是所有組件的父組件,所以數(shù)據(jù)放在App組件中,再使用props配置,所有的子組件就都可以訪問(wèn)到。

【App】(同時(shí)需要將數(shù)據(jù)傳遞到Item組件中,在當(dāng)前階段只能通過(guò)props配置一層一層往下傳,所以是 App-->List,List-->Item

1. 實(shí)現(xiàn)?App-->List?傳遞todos數(shù)據(jù)

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader></MyHeader><List :todos="todos"></List><MyFooter></MyFooter></div></div></div>
</template><script>import MyHeader from './components/MyHeader.vue'import List from './components/List.vue'import MyFooter from './components/MyFooter.vue'export default {name:'App',components:{MyHeader,List,MyFooter},data() {return {todos: [{id: '001', title: '吃飯', done: true},{id: '002', title: '學(xué)習(xí)', done: false},{id: '003', title: '追劇', done: true},]}},}
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>

2. List接受todos數(shù)據(jù)

<template><ul class="todo-main"><Item v-for="todo in todos" :key="todo.id"></Item></ul>
</template><script>import Item from './Item.vue'export default {name: 'List',components:{Item},props: ['todos']}
</script><style scoped>/*main*/.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;}
</style>

通過(guò)上述的代碼便可以根據(jù)數(shù)據(jù)的數(shù)量來(lái)渲染出幾個(gè)Item了,但是此時(shí)Item里面是沒(méi)有內(nèi)容的,所以需要?List-->Item 再次傳遞每條數(shù)據(jù)


3. 實(shí)現(xiàn)?List-->Item?傳遞todo數(shù)據(jù)

<template><ul class="todo-main"><Item v-for="todo in todos" :key="todo.id" :todo="todo"></Item></ul>
</template><script>import Item from './Item.vue'export default {name: 'List',components:{Item},props: ['todos']}
</script><style scoped>/*main*/.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;}
</style>

4. Item接受todo數(shù)據(jù)

<template> <li><label><input type="checkbox"/><span>{{todo.title}}</span></label><button class="btn btn-danger">刪除</button></li>
</template><script>export default {name: 'Item',// 聲明接收todo對(duì)象props:['todo'],}
</script><style scoped>/*item*/li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;}li label {float: left;cursor: pointer;}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;}li button {float: right;display: none;margin-top: 3px;}li:before {content: initial;}li:last-child {border-bottom: none;}li:hover {background-color: rgb(196, 195, 195);}li:hover button{display: block;}
</style>

4 實(shí)現(xiàn)添加數(shù)據(jù)

【App】定義接收數(shù)據(jù)的回調(diào)函數(shù)

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader :addTodo="addTodo"></MyHeader><List :todos="todos"></List><MyFooter></MyFooter></div></div></div>
</template><script>import MyHeader from './components/MyHeader.vue'import List from './components/List.vue'import MyFooter from './components/MyFooter.vue'export default {name:'App',components:{MyHeader,List,MyFooter},data() {return {todos: [{id: '001', title: '吃飯', done: true},{id: '002', title: '學(xué)習(xí)', done: false},{id: '003', title: '追劇', done: true},]}},methods: {// 添加一個(gè)todoaddTodo(todoObj) {this.todos.unshift(todoObj)}}}
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>

【MyHeader】實(shí)現(xiàn)添加數(shù)據(jù)的方法

<template><div class="todo-header"><!-- 綁定鍵盤(pán)回車(chē)事件 --><input type="text" placeholder="請(qǐng)輸入你的任務(wù)名稱,按回車(chē)鍵確認(rèn)" @keyup.enter="add" v-model="title"/></div>
</template><script>import {nanoid} from 'nanoid'  // 生成idexport default {name: 'MyHeader',data() {return {title: ''}},props: ['addTodo'],  // 接收父組件傳過(guò)來(lái)的addTodo函數(shù)methods: {add(e) {// 校驗(yàn)數(shù)據(jù)if (!this.title.trim()) return alert('輸入不能為空')// 將用戶的輸入包裝成為一個(gè)todo對(duì)象const todoObj = {id: nanoid(),/* title: e.target.value, */title: this.title,done: false}console.log(todoObj)// console.log(e.target.value)// console.log(this.title)// 通知App組件去添加一個(gè)todo對(duì)象this.addTodo(todoObj)// 清空輸入this.title = ''}}}
</script><style scoped>/*header*/.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;}.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);}
</style>

5 實(shí)現(xiàn)復(fù)選框勾選

【App】也是要逐層傳遞

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader :addTodo="addTodo"></MyHeader><List :todos="todos" :changeTodo="changeTodo"></List><MyFooter></MyFooter></div></div></div>
</template><script>import MyHeader from './components/MyHeader.vue'import List from './components/List.vue'import MyFooter from './components/MyFooter.vue'export default {name:'App',components:{MyHeader,List,MyFooter},data() {return {todos: [{id: '001', title: '吃飯', done: true},{id: '002', title: '學(xué)習(xí)', done: false},{id: '003', title: '追劇', done: true},]}},methods: {// 添加一個(gè)todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個(gè)todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},}}
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>

【List】

<template><ul class="todo-main"><Item v-for="todo in todos" :key="todo.id" :todo="todo":changeTodo="changeTodo"></Item></ul>
</template><script>import Item from './Item.vue'export default {name: 'List',components:{Item},props: ['todos', 'changeTodo']}
</script><style scoped>/*main*/.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;}
</style>

【Item】

<template> <li><label><input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/><span>{{todo.title}}</span></label><button class="btn btn-danger">刪除</button></li>
</template><script>export default {name: 'Item',// 聲明接收todo對(duì)象props:['todo', 'changeTodo'],methods: {// 勾選 or 取消勾選handleCheck(id) {// 通知 App組件將對(duì)應(yīng)的todo對(duì)象的狀態(tài)改變this.changeTodo(id)}}}
</script><style scoped>/*item*/li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;}li label {float: left;cursor: pointer;}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;}li button {float: right;display: none;margin-top: 3px;}li:before {content: initial;}li:last-child {border-bottom: none;}li:hover {background-color: rgb(196, 195, 195);}li:hover button{display: block;}
</style>

6 實(shí)現(xiàn)數(shù)據(jù)的刪除

【App】

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader :addTodo="addTodo"></MyHeader><List :todos="todos" :changeTodo="changeTodo" :deleteTodo="deleteTodo"></List><MyFooter></MyFooter></div></div></div>
</template><script>import MyHeader from './components/MyHeader.vue'import List from './components/List.vue'import MyFooter from './components/MyFooter.vue'export default {name:'App',components:{MyHeader,List,MyFooter},data() {return {todos: [{id: '001', title: '吃飯', done: true},{id: '002', title: '學(xué)習(xí)', done: false},{id: '003', title: '追劇', done: true},]}},methods: {// 添加一個(gè)todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個(gè)todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},// 刪除一個(gè)tododeleteTodo(id) {this.todos = this.todos.filter((todo) => todo.id !== id)},}}
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>

【List】

<template><ul class="todo-main"><Item v-for="todo in todos" :key="todo.id" :todo="todo":changeTodo="changeTodo":deleteTodo="deleteTodo"></Item></ul>
</template><script>import Item from './Item.vue'export default {name: 'List',components:{Item},props: ['todos', 'changeTodo', 'deleteTodo']}
</script><style scoped>/*main*/.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;}
</style>

【Item】

<template> <li><label><input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/><span>{{todo.title}}</span></label><button class="btn btn-danger" @click="handleDelete(todo.id)">刪除</button></li>
</template><script>export default {name: 'Item',// 聲明接收todo對(duì)象props:['todo', 'changeTodo', 'deleteTodo'],methods: {// 勾選 or 取消勾選handleCheck(id) {// 通知 App組件將對(duì)應(yīng)的todo對(duì)象的狀態(tài)改變this.changeTodo(id)},// 刪除操作handleDelete(id) {// console.log(id)if (confirm("確定刪除嗎?")) {// 通知App刪除this.deleteTodo(id)}}}}
</script><style scoped>/*item*/li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;}li label {float: left;cursor: pointer;}li label li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;}li button {float: right;display: none;margin-top: 3px;}li:before {content: initial;}li:last-child {border-bottom: none;}li:hover {background-color: rgb(196, 195, 195);}li:hover button{display: block;}
</style>

7 實(shí)現(xiàn)底部組件中數(shù)據(jù)的統(tǒng)計(jì)

【分析】如果想要統(tǒng)計(jì)數(shù)據(jù)的數(shù)量,就需要將數(shù)據(jù)傳遞到MyFooter組件中

【App】

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader :addTodo="addTodo"></MyHeader><List :todos="todos" :changeTodo="changeTodo" :deleteTodo="deleteTodo"></List><MyFooter:todos="todos"></MyFooter></div></div></div>
</template><script>import MyHeader from './components/MyHeader.vue'import List from './components/List.vue'import MyFooter from './components/MyFooter.vue'export default {name:'App',components:{MyHeader,List,MyFooter},data() {return {todos: [{id: '001', title: '吃飯', done: true},{id: '002', title: '學(xué)習(xí)', done: false},{id: '003', title: '追劇', done: true},]}},methods: {// 添加一個(gè)todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個(gè)todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},// 刪除一個(gè)tododeleteTodo(id) {this.todos = this.todos.filter((todo) => todo.id !== id)},}}
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>

【MyFooter】

在這個(gè)組件中可以使用計(jì)算屬性實(shí)現(xiàn)數(shù)據(jù)的總長(zhǎng)度和被勾選的數(shù)據(jù)的計(jì)算

<template><div class="todo-footer" v-if="todosLength"><label><input type="checkbox"/></label><span><span>已完成 {{doneTotal}}</span> / {{todosLength}}</span><button class="btn btn-danger">清除已完成任務(wù)</button></div>
</template><script>
export default {name: 'MyFooter',props: ['todos'],computed: {todosLength() {return this.todos.length},doneTotal() {return this.todos.filter(todo => todo.done).length// 也可以使用下面求和來(lái)實(shí)現(xiàn)// return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0)}}
}
</script><style scoped>/*footer*/.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}
</style>

8 實(shí)現(xiàn)勾選全部的小復(fù)選框來(lái)實(shí)現(xiàn)大復(fù)選框的勾選

:checked="isAll"

isAll也是通過(guò)計(jì)算屬性計(jì)算得來(lái)的

【MyFooter】?

<template><div class="todo-footer" v-if="todosLength"><label><input type="checkbox" :checked="isAll"/></label><span><span>已完成 {{doneTotal}}</span> / {{todosLength}}</span><button class="btn btn-danger">清除已完成任務(wù)</button></div>
</template><script>
export default {name: 'MyFooter',props: ['todos'],computed: {todosLength() {return this.todos.length},doneTotal() {return this.todos.filter(todo => todo.done).length// 也可以使用下面求和來(lái)實(shí)現(xiàn)// return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0)},isAll() {return this.doneTotal === this.todosLength && this.todosLength > 0}, }
}
</script><style scoped>/*footer*/.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}
</style>

9 實(shí)現(xiàn)勾選大復(fù)選框來(lái)實(shí)現(xiàn)所有的小復(fù)選框都被勾選

【App】

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader :addTodo="addTodo"></MyHeader><List :todos="todos" :changeTodo="changeTodo" :deleteTodo="deleteTodo"></List><MyFooter:todos="todos":checkAllTodo="checkAllTodo"></MyFooter></div></div></div>
</template><script>import MyHeader from './components/MyHeader.vue'import List from './components/List.vue'import MyFooter from './components/MyFooter.vue'export default {name:'App',components:{MyHeader,List,MyFooter},data() {return {todos: [{id: '001', title: '吃飯', done: true},{id: '002', title: '學(xué)習(xí)', done: false},{id: '003', title: '追劇', done: true},]}},methods: {// 添加一個(gè)todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個(gè)todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},// 刪除一個(gè)tododeleteTodo(id) {this.todos = this.todos.filter((todo) => todo.id !== id)},// 全選or取消全選checkAllTodo(done) {this.todos.forEach((todo) => {todo.done = done})},}}
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>

【MyFooter】

<template><div class="todo-footer" v-if="todosLength"><label><input type="checkbox" :checked="isAll" @change="checkAll"/></label><span><span>已完成 {{doneTotal}}</span> / {{todosLength}}</span><button class="btn btn-danger">清除已完成任務(wù)</button></div>
</template><script>
export default {name: 'MyFooter',props: ['todos', 'checkAllTodo'],computed: {todosLength() {return this.todos.length},doneTotal() {return this.todos.filter(todo => todo.done).length// 也可以使用下面求和來(lái)實(shí)現(xiàn)// return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0)},isAll() {return this.doneTotal === this.todosLength && this.todosLength > 0}, },methods: {checkAll(e) {this.checkAllTodo(e.target.checked)}}
}
</script><style scoped>/*footer*/.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}
</style>

10 清空所有數(shù)據(jù)

【App】

<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader :addTodo="addTodo"></MyHeader><List :todos="todos" :changeTodo="changeTodo" :deleteTodo="deleteTodo"></List><MyFooter:todos="todos":checkAllTodo="checkAllTodo":clearAllTodo="clearAllTodo"></MyFooter></div></div></div>
</template><script>import MyHeader from './components/MyHeader.vue'import List from './components/List.vue'import MyFooter from './components/MyFooter.vue'export default {name:'App',components:{MyHeader,List,MyFooter},data() {return {todos: [{id: '001', title: '吃飯', done: true},{id: '002', title: '學(xué)習(xí)', done: false},{id: '003', title: '追劇', done: true},]}},methods: {// 添加一個(gè)todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個(gè)todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},// 刪除一個(gè)tododeleteTodo(id) {this.todos = this.todos.filter((todo) => todo.id !== id)},// 全選or取消全選checkAllTodo(done) {this.todos.forEach((todo) => {todo.done = done})},// 清空所有已經(jīng)完成的todoclearAllTodo() {this.todos = this.todos.filter((todo) => !todo.done)}}}
</script><style>/*base*/body {background: #fff;}.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);border-radius: 4px;}.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;}.btn-danger:hover {color: #fff;background-color: #bd362f;}.btn:focus {outline: none;}.todo-container {width: 600px;margin: 0 auto;}.todo-container .todo-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;}
</style>

【MyFooter】

<template><div class="todo-footer" v-if="todosLength"><label><input type="checkbox" :checked="isAll" @change="checkAll"/></label><span><span>已完成 {{doneTotal}}</span> / {{todosLength}}</span><button class="btn btn-danger"  @click="clearTodo">清除已完成任務(wù)</button></div>
</template><script>
export default {name: 'MyFooter',props: ['todos', 'checkAllTodo', 'clearAllTodo'],computed: {todosLength() {return this.todos.length},doneTotal() {return this.todos.filter(todo => todo.done).length// 也可以使用下面求和來(lái)實(shí)現(xiàn)// return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0)},isAll() {return this.doneTotal === this.todosLength && this.todosLength > 0}, },methods: {checkAll(e) {this.checkAllTodo(e.target.checked)},clearTodo() {this.clearAllTodo()}}
}
</script><style scoped>/*footer*/.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;}.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;}.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;}.todo-footer button {float: right;margin-top: 5px;}
</style>

11 實(shí)現(xiàn)案例中的數(shù)據(jù)存入本地存儲(chǔ)

【分析】首先我們要知道什么時(shí)候需要將數(shù)據(jù)存入本地存儲(chǔ)?所以這就用到了watch監(jiān)聽(tīng),當(dāng)todos的值發(fā)生變化時(shí),將新的值存入本地存儲(chǔ)。

又因?yàn)楫?dāng)我們勾選復(fù)選框時(shí),我們發(fā)現(xiàn)本地存儲(chǔ)中的 done 值并沒(méi)有發(fā)生變化?這主要是因?yàn)楸O(jiān)聽(tīng)默認(rèn)只會(huì)監(jiān)聽(tīng)第一層,如果想要監(jiān)聽(tīng)對(duì)象中某個(gè)數(shù)據(jù)發(fā)生變化時(shí),就需要深度監(jiān)視了。

【App】

這里使用 || 運(yùn)算可以防止一開(kāi)始本地存儲(chǔ)中沒(méi)有數(shù)據(jù)而報(bào)錯(cuò)

12 案例中使用自定義事件完成組件間的數(shù)據(jù)通信

這邊以添加數(shù)據(jù)為例

【App】

給發(fā)送數(shù)據(jù)的組件綁定自定義事件

<MyHeader @addTodo="addTodo"></MyHeader>...methods: {// 添加一個(gè)todoaddTodo(todoObj) {this.todos.unshift(todoObj)},
}

【MyHeader】

13 案例中實(shí)現(xiàn)數(shù)據(jù)的編輯

需求分析:當(dāng)點(diǎn)擊編輯按鈕時(shí),變成input表單修改數(shù)據(jù),此時(shí)編輯按鈕隱藏,當(dāng)失去焦點(diǎn)時(shí),編輯完成,顯示編輯后的數(shù)據(jù),同時(shí)編輯按鈕顯示。

?這邊使用全局事件總線來(lái)實(shí)現(xiàn)通信

【App】

        methods: {...// 更改updateTodo(id,title) {this.todos.forEach((todo) => {if (todo.id === id) todo.title = title})},...},mounted() {this.$bus.$on('updateTodo', this.updateTodo)},beforeDestroy() {this.$bus.$off('updateTodo')}

【Item】



因?yàn)槿绻胍ソ裹c(diǎn)時(shí)實(shí)現(xiàn)數(shù)據(jù)的修改,那么你必須提前獲取焦點(diǎn),但是由于Vue的執(zhí)行機(jī)制,當(dāng)Vue底層監(jiān)視到數(shù)據(jù)發(fā)生改變時(shí),它并不會(huì)立即去重新渲染模板,而是繼續(xù)執(zhí)行后面的代碼,所以如果不加以處理的話,直接獲取焦點(diǎn),肯定會(huì)報(bào)錯(cuò),因?yàn)轫?yè)面中的元素還沒(méi)有加載解析出,找不到獲取焦點(diǎn)的input元素,所以可以通過(guò)以下的代碼實(shí)現(xiàn)

this.$nextTick(function() {  // 告訴Vue,DOM渲染完畢后,再執(zhí)行focus()方法this.$refs.inputTiltle.focus()
})

14 實(shí)現(xiàn)數(shù)據(jù)進(jìn)出的動(dòng)畫(huà)效果

【Item】

使用<transtion></transtion>標(biāo)簽包裹


http://www.risenshineclean.com/news/34986.html

相關(guān)文章:

  • 深圳網(wǎng)站建設(shè)代理商哪家網(wǎng)絡(luò)推廣好
  • 外貿(mào)購(gòu)物網(wǎng)站短視頻如何引流與推廣
  • 做視頻網(wǎng)站怎么掙錢(qián)有沒(méi)有免費(fèi)的推廣網(wǎng)站
  • 晉江網(wǎng)站建設(shè)公司網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣方案怎么寫(xiě)
  • wordpress分詞seo項(xiàng)目培訓(xùn)
  • 百度競(jìng)價(jià)點(diǎn)擊軟件網(wǎng)站seo整站優(yōu)化
  • 微信輔助網(wǎng)站制作論壇排名
  • 免費(fèi)的logo設(shè)計(jì)網(wǎng)站推廣運(yùn)營(yíng)怎么做
  • 微網(wǎng)站開(kāi)發(fā)北京關(guān)鍵詞優(yōu)化一年的收費(fèi)標(biāo)準(zhǔn)
  • 東莞網(wǎng)站開(kāi)發(fā)站長(zhǎng)之家網(wǎng)站排行榜
  • 濰坊網(wǎng)站建設(shè)(首選聚搜網(wǎng)絡(luò))cps推廣平臺(tái)有哪些
  • wordpress cdn圖片加速常用的seo查詢工具
  • 網(wǎng)站視頻建設(shè)常德論壇網(wǎng)站
  • 購(gòu)物網(wǎng)站最重要的功能專業(yè)網(wǎng)頁(yè)設(shè)計(jì)和網(wǎng)站制作公司
  • 網(wǎng)站查詢域名訪問(wèn)網(wǎng)絡(luò)營(yíng)銷(xiāo)渠道建設(shè)方案
  • 公司的網(wǎng)站建設(shè)一般需要多少費(fèi)用sem優(yōu)化怎么做
  • 中英文網(wǎng)站asp怎么做seo推廣軟件費(fèi)用
  • 找人做網(wǎng)站應(yīng)該注意什么福州seo兼職
  • 打開(kāi)鏈接的網(wǎng)站網(wǎng)絡(luò)營(yíng)銷(xiāo)計(jì)劃的七個(gè)步驟
  • 自制網(wǎng)站的動(dòng)態(tài)圖怎么做創(chuàng)意廣告
  • 廣州中小企業(yè)網(wǎng)站建設(shè)免費(fèi)發(fā)帖推廣的平臺(tái)
  • 深圳外文網(wǎng)站制作喬拓云智能建站官網(wǎng)
  • 福州企業(yè)網(wǎng)站推廣網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣方式
  • 馬鞍山制作網(wǎng)站網(wǎng)絡(luò)營(yíng)銷(xiāo)方式有哪幾種
  • 學(xué)校網(wǎng)站制作2345網(wǎng)址導(dǎo)航大全
  • 做二手房的網(wǎng)站技巧網(wǎng)站做成app
  • 網(wǎng)站設(shè)計(jì)價(jià)格大概多少谷歌瀏覽器下載手機(jī)版
  • 做網(wǎng)站優(yōu)化給業(yè)務(wù)員提成百度資源提交
  • wordpress+admin主題武漢seo招聘信息
  • 揚(yáng)中網(wǎng)站建設(shè) 優(yōu)幫云站長(zhǎng)工具seo查詢5g5g