当前位置: 首页 > news >正文

网站优化培训都有哪些可以做app的网站

网站优化培训,都有哪些可以做app的网站,多用户购物商城源码,网络规划设计师2022预测案例模拟题目录 1 拿到一个功能模块首先需要拆分组件#xff1a; 2 使用组件实现静态页面的效果 3 分析数据保存在哪个组件 4 实现添加数据 5 实现复选框勾选 6 实现数据的删除 7 实现底部组件中数据的统计 8 实现勾选全部的小复选框来实现大复选框的勾选 9 实现勾选大复选框来…目录 1 拿到一个功能模块首先需要拆分组件 2 使用组件实现静态页面的效果 3 分析数据保存在哪个组件 4 实现添加数据 5 实现复选框勾选 6 实现数据的删除 7 实现底部组件中数据的统计 8 实现勾选全部的小复选框来实现大复选框的勾选 9 实现勾选大复选框来实现所有的小复选框都被勾选 10 清空所有数据 11 实现案例中的数据存入本地存储 12 案例中使用自定义事件完成组件间的数据通信 13 案例中实现数据的编辑 14 实现数据进出的动画效果 【分析】组件化编码的流程 1. 实现静态组件抽取组件使用组件实现静态页面效果 2.展示动态数据 2.1 数据的类型、名称是什么 2.2 数据保存在哪个组件 3.交互---从绑定事件监听开始 1 拿到一个功能模块首先需要拆分组件 2 使用组件实现静态页面的效果 【main.js】 import Vue from vue import App from ./App.vueVue.config.productionTip falsenew Vue({el: #app,render: h h(App) }) 【MyHeader】 templatediv classtodo-headerinput typetext//div /templatescriptexport default {name: MyHeader,} /scriptstyle 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 lilabelinput typecheckbox/span v-fortodo in todos :keytodo.id{{todo.title}}/span/labelbutton classbtn btn-danger删除/button/li /templatescriptexport default {name: Item,data() {return {todos: [{id: 001, title: 吃饭, done: true},{id: 002, title: 学习, done: false},{id: 003, title: 追剧, done: true},]}},} /scriptstyle 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】 templateul classtodo-mainItem/ItemItem/Item/ul /templatescriptimport Item from ./Item.vueexport default {name: List,components:{Item},} /scriptstyle 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】 templatediv classtodo-footerlabelinput typecheckbox//labelspanspan已完成 0/span / 3/spanbutton classbtn btn-danger清除已完成任务/button/div /templatescriptexport default {name: MyFooter,} /scriptstyle 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】  templatediv idrootdiv classtodo-containerdiv classtodo-wrapMyHeader/MyHeaderList/ListMyFooter/MyFooter/div/div/div /templatescriptimport MyHeader from ./components/MyHeader.vueimport List from ./components/List.vueimport MyFooter from ./components/MyFooter.vueexport default {name:App,components:{MyHeader,List,MyFooter} } /scriptstyle/*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 通过以上代码就可以实现静态页面的效果了 3 分析数据保存在哪个组件 在上述代码中数据是保存在Item组件中的但是如果想要在后续实现一系列交互效果在MyHeader组件中需要添加数据而MyHeader组件和Item组件没有直接的关系 就当前学习阶段的知识而言并不能实现这两个组件之间的通信(后续会有解决方案)同理MyFooter也一样。 【分析】因为App组件是所有组件的父组件所以数据放在App组件中再使用props配置所有的子组件就都可以访问到。 【App】同时需要将数据传递到Item组件中在当前阶段只能通过props配置一层一层往下传所以是 App--ListList--Item 1. 实现 App--List 传递todos数据 templatediv idrootdiv classtodo-containerdiv classtodo-wrapMyHeader/MyHeaderList :todostodos/ListMyFooter/MyFooter/div/div/div /templatescriptimport MyHeader from ./components/MyHeader.vueimport List from ./components/List.vueimport MyFooter from ./components/MyFooter.vueexport default {name:App,components:{MyHeader,List,MyFooter},data() {return {todos: [{id: 001, title: 吃饭, done: true},{id: 002, title: 学习, done: false},{id: 003, title: 追剧, done: true},]}},} /scriptstyle/*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数据 templateul classtodo-mainItem v-fortodo in todos :keytodo.id/Item/ul /templatescriptimport Item from ./Item.vueexport default {name: List,components:{Item},props: [todos]} /scriptstyle 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了但是此时Item里面是没有内容的所以需要 List--Item 再次传递每条数据 3. 实现 List--Item 传递todo数据 templateul classtodo-mainItem v-fortodo in todos :keytodo.id :todotodo/Item/ul /templatescriptimport Item from ./Item.vueexport default {name: List,components:{Item},props: [todos]} /scriptstyle 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数据 template lilabelinput typecheckbox/span{{todo.title}}/span/labelbutton classbtn btn-danger删除/button/li /templatescriptexport default {name: Item,// 声明接收todo对象props:[todo],} /scriptstyle 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 实现添加数据 【App】定义接收数据的回调函数 templatediv idrootdiv classtodo-containerdiv classtodo-wrapMyHeader :addTodoaddTodo/MyHeaderList :todostodos/ListMyFooter/MyFooter/div/div/div /templatescriptimport MyHeader from ./components/MyHeader.vueimport List from ./components/List.vueimport MyFooter from ./components/MyFooter.vueexport default {name:App,components:{MyHeader,List,MyFooter},data() {return {todos: [{id: 001, title: 吃饭, done: true},{id: 002, title: 学习, done: false},{id: 003, title: 追剧, done: true},]}},methods: {// 添加一个todoaddTodo(todoObj) {this.todos.unshift(todoObj)}}} /scriptstyle/*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】实现添加数据的方法 templatediv classtodo-header!-- 绑定键盘回车事件 --input typetext placeholder请输入你的任务名称按回车键确认 keyup.enteradd v-modeltitle//div /templatescriptimport {nanoid} from nanoid // 生成idexport default {name: MyHeader,data() {return {title: }},props: [addTodo], // 接收父组件传过来的addTodo函数methods: {add(e) {// 校验数据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 }}} /scriptstyle 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 实现复选框勾选 【App】也是要逐层传递 templatediv idrootdiv classtodo-containerdiv classtodo-wrapMyHeader :addTodoaddTodo/MyHeaderList :todostodos :changeTodochangeTodo/ListMyFooter/MyFooter/div/div/div /templatescriptimport MyHeader from ./components/MyHeader.vueimport List from ./components/List.vueimport MyFooter from ./components/MyFooter.vueexport default {name:App,components:{MyHeader,List,MyFooter},data() {return {todos: [{id: 001, title: 吃饭, done: true},{id: 002, title: 学习, 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})},}} /scriptstyle/*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】 templateul classtodo-mainItem v-fortodo in todos :keytodo.id :todotodo:changeTodochangeTodo/Item/ul /templatescriptimport Item from ./Item.vueexport default {name: List,components:{Item},props: [todos, changeTodo]} /scriptstyle 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 lilabelinput typecheckbox :checkedtodo.done changehandleCheck(todo.id)/span{{todo.title}}/span/labelbutton classbtn btn-danger删除/button/li /templatescriptexport default {name: Item,// 声明接收todo对象props:[todo, changeTodo],methods: {// 勾选 or 取消勾选handleCheck(id) {// 通知 App组件将对应的todo对象的状态改变this.changeTodo(id)}}} /scriptstyle 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 实现数据的删除 【App】 templatediv idrootdiv classtodo-containerdiv classtodo-wrapMyHeader :addTodoaddTodo/MyHeaderList :todostodos :changeTodochangeTodo :deleteTododeleteTodo/ListMyFooter/MyFooter/div/div/div /templatescriptimport MyHeader from ./components/MyHeader.vueimport List from ./components/List.vueimport MyFooter from ./components/MyFooter.vueexport default {name:App,components:{MyHeader,List,MyFooter},data() {return {todos: [{id: 001, title: 吃饭, done: true},{id: 002, title: 学习, 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)},}} /scriptstyle/*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】 templateul classtodo-mainItem v-fortodo in todos :keytodo.id :todotodo:changeTodochangeTodo:deleteTododeleteTodo/Item/ul /templatescriptimport Item from ./Item.vueexport default {name: List,components:{Item},props: [todos, changeTodo, deleteTodo]} /scriptstyle 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 lilabelinput typecheckbox :checkedtodo.done changehandleCheck(todo.id)/span{{todo.title}}/span/labelbutton classbtn btn-danger clickhandleDelete(todo.id)删除/button/li /templatescriptexport default {name: Item,// 声明接收todo对象props:[todo, changeTodo, deleteTodo],methods: {// 勾选 or 取消勾选handleCheck(id) {// 通知 App组件将对应的todo对象的状态改变this.changeTodo(id)},// 删除操作handleDelete(id) {// console.log(id)if (confirm(确定删除吗)) {// 通知App删除this.deleteTodo(id)}}}} /scriptstyle 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 实现底部组件中数据的统计 【分析】如果想要统计数据的数量就需要将数据传递到MyFooter组件中 【App】 templatediv idrootdiv classtodo-containerdiv classtodo-wrapMyHeader :addTodoaddTodo/MyHeaderList :todostodos :changeTodochangeTodo :deleteTododeleteTodo/ListMyFooter:todostodos/MyFooter/div/div/div /templatescriptimport MyHeader from ./components/MyHeader.vueimport List from ./components/List.vueimport MyFooter from ./components/MyFooter.vueexport default {name:App,components:{MyHeader,List,MyFooter},data() {return {todos: [{id: 001, title: 吃饭, done: true},{id: 002, title: 学习, 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)},}} /scriptstyle/*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】 在这个组件中可以使用计算属性实现数据的总长度和被勾选的数据的计算 templatediv classtodo-footer v-iftodosLengthlabelinput typecheckbox//labelspanspan已完成 {{doneTotal}}/span / {{todosLength}}/spanbutton classbtn btn-danger清除已完成任务/button/div /templatescript export default {name: MyFooter,props: [todos],computed: {todosLength() {return this.todos.length},doneTotal() {return this.todos.filter(todo todo.done).length// 也可以使用下面求和来实现// return this.todos.reduce((pre, todo) pre (todo.done ? 1 : 0), 0)}} } /scriptstyle 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 实现勾选全部的小复选框来实现大复选框的勾选 :checkedisAll isAll也是通过计算属性计算得来的 【MyFooter】  templatediv classtodo-footer v-iftodosLengthlabelinput typecheckbox :checkedisAll//labelspanspan已完成 {{doneTotal}}/span / {{todosLength}}/spanbutton classbtn btn-danger清除已完成任务/button/div /templatescript export default {name: MyFooter,props: [todos],computed: {todosLength() {return this.todos.length},doneTotal() {return this.todos.filter(todo todo.done).length// 也可以使用下面求和来实现// return this.todos.reduce((pre, todo) pre (todo.done ? 1 : 0), 0)},isAll() {return this.doneTotal this.todosLength this.todosLength 0}, } } /scriptstyle 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 实现勾选大复选框来实现所有的小复选框都被勾选 【App】 templatediv idrootdiv classtodo-containerdiv classtodo-wrapMyHeader :addTodoaddTodo/MyHeaderList :todostodos :changeTodochangeTodo :deleteTododeleteTodo/ListMyFooter:todostodos:checkAllTodocheckAllTodo/MyFooter/div/div/div /templatescriptimport MyHeader from ./components/MyHeader.vueimport List from ./components/List.vueimport MyFooter from ./components/MyFooter.vueexport default {name:App,components:{MyHeader,List,MyFooter},data() {return {todos: [{id: 001, title: 吃饭, done: true},{id: 002, title: 学习, 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})},}} /scriptstyle/*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】 templatediv classtodo-footer v-iftodosLengthlabelinput typecheckbox :checkedisAll changecheckAll//labelspanspan已完成 {{doneTotal}}/span / {{todosLength}}/spanbutton classbtn btn-danger清除已完成任务/button/div /templatescript export default {name: MyFooter,props: [todos, checkAllTodo],computed: {todosLength() {return this.todos.length},doneTotal() {return this.todos.filter(todo todo.done).length// 也可以使用下面求和来实现// 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)}} } /scriptstyle 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 清空所有数据 【App】 templatediv idrootdiv classtodo-containerdiv classtodo-wrapMyHeader :addTodoaddTodo/MyHeaderList :todostodos :changeTodochangeTodo :deleteTododeleteTodo/ListMyFooter:todostodos:checkAllTodocheckAllTodo:clearAllTodoclearAllTodo/MyFooter/div/div/div /templatescriptimport MyHeader from ./components/MyHeader.vueimport List from ./components/List.vueimport MyFooter from ./components/MyFooter.vueexport default {name:App,components:{MyHeader,List,MyFooter},data() {return {todos: [{id: 001, title: 吃饭, done: true},{id: 002, title: 学习, 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})},// 清空所有已经完成的todoclearAllTodo() {this.todos this.todos.filter((todo) !todo.done)}}} /scriptstyle/*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】 templatediv classtodo-footer v-iftodosLengthlabelinput typecheckbox :checkedisAll changecheckAll//labelspanspan已完成 {{doneTotal}}/span / {{todosLength}}/spanbutton classbtn btn-danger clickclearTodo清除已完成任务/button/div /templatescript export default {name: MyFooter,props: [todos, checkAllTodo, clearAllTodo],computed: {todosLength() {return this.todos.length},doneTotal() {return this.todos.filter(todo todo.done).length// 也可以使用下面求和来实现// 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()}} } /scriptstyle 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 实现案例中的数据存入本地存储 【分析】首先我们要知道什么时候需要将数据存入本地存储所以这就用到了watch监听当todos的值发生变化时将新的值存入本地存储。 又因为当我们勾选复选框时我们发现本地存储中的 done 值并没有发生变化这主要是因为监听默认只会监听第一层如果想要监听对象中某个数据发生变化时就需要深度监视了。 【App】 这里使用 || 运算可以防止一开始本地存储中没有数据而报错 12 案例中使用自定义事件完成组件间的数据通信 这边以添加数据为例 【App】 给发送数据的组件绑定自定义事件 MyHeader addTodoaddTodo/MyHeader...methods: {// 添加一个todoaddTodo(todoObj) {this.todos.unshift(todoObj)}, } 【MyHeader】 13 案例中实现数据的编辑 需求分析当点击编辑按钮时变成input表单修改数据此时编辑按钮隐藏当失去焦点时编辑完成显示编辑后的数据同时编辑按钮显示。 这边使用全局事件总线来实现通信 【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】 因为如果想要失去焦点时实现数据的修改那么你必须提前获取焦点但是由于Vue的执行机制当Vue底层监视到数据发生改变时它并不会立即去重新渲染模板而是继续执行后面的代码所以如果不加以处理的话直接获取焦点肯定会报错因为页面中的元素还没有加载解析出找不到获取焦点的input元素所以可以通过以下的代码实现 this.$nextTick(function() { // 告诉VueDOM渲染完毕后再执行focus()方法this.$refs.inputTiltle.focus() }) 14 实现数据进出的动画效果 【Item】 使用transtion/transtion标签包裹
http://www.zqtcl.cn/news/897787/

相关文章:

  • 企业网站建设的重要性和必要性深圳设计网站排行
  • 山西省网站建设河南省考生服务平台官网
  • 做水产的都用什么网站wordpress 前端登陆
  • 商务网站建设网站开发一个软件开发的流程
  • 网站建设电脑和手机有区别吗公众号登录微信入口
  • 天津市建设监理协会网站三亚网络网站建设
  • 义乌进货网平台北京网优化seo优化公司
  • 在网站上放广告网站建设流程效果
  • 腾讯云学生机做网站济南网站改版
  • 开封市做网站的公司wordpress无法映射
  • 网站构建工具wordpress 主题授权
  • 大型网站开发 赚钱宁夏网站建设优化
  • 通过ip访问网站需要怎么做博客的网站页面设计
  • 高明做网站软件开发工程师是前端还是后端
  • 利用html5 监控网站性能如何能快速搜到新做网站链接
  • 做网站需要看那几点seo是什么职业岗位
  • 做游戏网站需要哪些许可100个免费推广网站下载
  • 网站管理系统是什么马鞍山网站建设制作公司
  • 设计学网站网络工程专业毕业生设计
  • 成都网站建设有名的国外优质设计网站
  • seo基础培训教程seo百度关键词优化软件
  • 西安响应式网站青岛网站制作哪里有
  • 政务服务网站建设合肥seo排名扣费
  • 郑州做网站的大公司无锡网站程序
  • 打开网站是空白页面营销型网站建设应该考虑哪些因素
  • 做网站开麻烦吗个人网站备案网站名称
  • 瑞诺国际做外贸网站好吗网站端和移动端分开建设域名一样么
  • 如何网站点击率网站程序开发技术
  • 深圳网站建设售后服务怎样.net网站开发简介
  • 光谷软件园 网站建设中国国家数据统计网