国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

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

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

目錄

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

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

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

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

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

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

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

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

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

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

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

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

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

14 實現(xiàn)數(shù)據(jù)進出的動畫效果


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

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

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

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

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

3.交互---從綁定事件監(jiān)聽開始


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


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

【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>

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

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

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


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

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

1. 實現(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>

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


3. 實現(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對象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 實現(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: {// 添加一個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】實現(xiàn)添加數(shù)據(jù)的方法

<template><div class="todo-header"><!-- 綁定鍵盤回車事件 --><input type="text" placeholder="請輸入你的任務(wù)名稱,按回車鍵確認" @keyup.enter="add" v-model="title"/></div>
</template><script>import {nanoid} from 'nanoid'  // 生成idexport default {name: 'MyHeader',data() {return {title: ''}},props: ['addTodo'],  // 接收父組件傳過來的addTodo函數(shù)methods: {add(e) {// 校驗數(shù)據(jù)if (!this.title.trim()) return alert('輸入不能為空')// 將用戶的輸入包裝成為一個todo對象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組件去添加一個todo對象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 實現(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: {// 添加一個todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個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對象props:['todo', 'changeTodo'],methods: {// 勾選 or 取消勾選handleCheck(id) {// 通知 App組件將對應(yīng)的todo對象的狀態(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 實現(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: {// 添加一個todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},// 刪除一個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對象props:['todo', 'changeTodo', 'deleteTodo'],methods: {// 勾選 or 取消勾選handleCheck(id) {// 通知 App組件將對應(yīng)的todo對象的狀態(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 實現(xiàn)底部組件中數(shù)據(jù)的統(tǒng)計

【分析】如果想要統(tǒng)計數(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: {// 添加一個todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},// 刪除一個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】

在這個組件中可以使用計算屬性實現(xiàn)數(shù)據(jù)的總長度和被勾選的數(shù)據(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// 也可以使用下面求和來實現(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 實現(xiàn)勾選全部的小復(fù)選框來實現(xiàn)大復(fù)選框的勾選

:checked="isAll"

isAll也是通過計算屬性計算得來的

【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// 也可以使用下面求和來實現(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 實現(xiàn)勾選大復(fù)選框來實現(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: {// 添加一個todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},// 刪除一個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// 也可以使用下面求和來實現(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: {// 添加一個todoaddTodo(todoObj) {this.todos.unshift(todoObj)},// 勾選或者取消勾選一個todochangeTodo(id) {this.todos.forEach((todo) => {if (todo.id === id) todo.done = !todo.done})},// 刪除一個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// 也可以使用下面求和來實現(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 實現(xiàn)案例中的數(shù)據(jù)存入本地存儲

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

又因為當我們勾選復(fù)選框時,我們發(fā)現(xiàn)本地存儲中的 done 值并沒有發(fā)生變化?這主要是因為監(jiān)聽默認只會監(jiān)聽第一層,如果想要監(jiān)聽對象中某個數(shù)據(jù)發(fā)生變化時,就需要深度監(jiān)視了。

【App】

這里使用 || 運算可以防止一開始本地存儲中沒有數(shù)據(jù)而報錯

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

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

【App】

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

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

【MyHeader】

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

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

?這邊使用全局事件總線來實現(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】



因為如果想要失去焦點時實現(xiàn)數(shù)據(jù)的修改,那么你必須提前獲取焦點,但是由于Vue的執(zhí)行機制,當Vue底層監(jiān)視到數(shù)據(jù)發(fā)生改變時,它并不會立即去重新渲染模板,而是繼續(xù)執(zhí)行后面的代碼,所以如果不加以處理的話,直接獲取焦點,肯定會報錯,因為頁面中的元素還沒有加載解析出,找不到獲取焦點的input元素,所以可以通過以下的代碼實現(xiàn)

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

14 實現(xiàn)數(shù)據(jù)進出的動畫效果

【Item】

使用<transtion></transtion>標簽包裹


http://aloenet.com.cn/news/34986.html

相關(guān)文章:

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