用本地存储改写前面的todo案例
<template> <li> <label > <input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/> <span v-show="!todo.isEdit">{{todo.title}}</span> <input type="text" :value="todo.title" v-show="todo.isEdit" @blur="handleBlur(todo,$event)" ref="inputTitle" > </label> <button class="btn btn-danger" @click="deleteID(todo.id)">删除</button> <button v-show="!todo.isEdit" class="btn btn-edit" @click="handleEdit(todo)" >编辑</button> </li> </template>
<script> export default { nmae:'Item', //接受对象 props:['todo'], methods: { handleCheck(id){ //通知APP取反 this.$bus.$emit('checkTodo',id) }, deleteID(id){ if(confirm('确认删除么?')){ this.$bus.$emit('deleteTodo',id) } }, //编辑 handleEdit(todo){ if(Object.hasOwnProperty.call(todo, 'isEdit')){ todo.isEdit = true }else{ this.$set(todo,'isEdit',true) //响应式的 } this.$nextTick(function(){ this.$refs.inputTitle.focus() }) }, handleBlur(todo,e){ todo.isEdit = false if(!e.target.value.trim()) return alert('输入不能为空') this.$bus.$emit('updateTodo',todo.id,e.target.value) } }, } </script>
<style scoped> 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; margin-top: 3px; }
li::before{ content: initial; }
li:last-child{ border-bottom: none; } </style> <template> <ul class="todo-main"> <Item v-for="(todoObj) in todos" :key="todoObj.id" :todo="todoObj" /> </ul> </template>
<script> import Item from './Item.vue' export default { nmae:'List', components:{ Item }, props:['todos'] } </script>
<style scoped> .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> <template> <div class="todo-footer" v-show="todos.length"> <label> <input type="checkbox" :checked="isAll" @change="checkAll"> </label> <span> <span>已完成{{doneTotal}}/全部{{ todos.length }}</span> </span> <button class="btn btn-danger" @click="clearAll">清除已完成任务</button> </div> </template>
<script> export default { nmae:'MyFooter', props:['todos','checkAllTodo','clearTotal'], computed:{ doneTotal(){ return this.todos.reduce((pre,current)=>pre + (current.done ? 1 : 0),0) }, isAll(){ return this.doneTotal === this.todos.length && this.todos.length > 0 } }, methods:{ checkAll(e){ this.checkAllTodo(e.target.checked) }, clearAll(){ this.clearTotal() } } } </script>
<style scoped> .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> <template> <div class="todo-header"> <input type="text" placeholder="请输入你的任务名称按回车确认" @keyup.enter="add" /> </div> </template>
<script> import {nanoid} from 'nanoid' export default { nmae:'Top', methods: { add(element){ //校验数据 if(!element.target.value) return //将用户输入包装成一个todo对象 const todoObj = {id:nanoid(),title:element.target.value,done:false} this.$emit('addTodo',todoObj) element.target.value='' } }, } </script>
<style scoped> .to-header input{ width: 700px; 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.8); } </style> 标签:vue,07,todo,li,1px,margin,height,border From: https://www.cnblogs.com/hbro/p/18041218