编辑todo,代码涉及的主要文件有
- store/index.js
- App.vue,即App组件
- components/Item.vue,即Item组件
App.vue(App组件)
变更部分:添加样式.btn-edit 。
<template>
<div id="app">
<div class="todo-container">
<div class="todo-wrap">
<Header/>
<List/>
<Footer/>
</div>
</div>
</div>
</template>
<script>
import Header from './components/Header.vue';
import List from "./components/List.vue";
import Footer from "./components/Footer.vue";
export default {
name: 'App',
components: {
Header,
List,
Footer
}
}
</script>
<style>
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-edit{
color: #fff;
background-color: orange;
border: 1px solid darkorange;
margin-right: 5px;
}
.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>
store/index.js
变更部分:添加mutation方法UPDATE_TODO 。
import Vue from "vue";
import Vuex, { Store } from "vuex";
Vue.use(Vuex);
const state = {
todos:[
{id:"001",title:"吃饭",done:true},
{id:"002",title:"睡觉",done:true},
{id:"003",title:"打豆豆",done:false},
]
}
const getters = {
total(state){
return state.todos.length;
},
doneTotal(state){
return state.todos.reduce((pre,todo) => { return pre + (todo.done ? 1 : 0)}, 0)
},
isAllChecked(state,getters){
return getters.total > 0 && getters.total === getters.doneTotal
}
}
const actions = {}
const mutations = {
ADD_TODO(state,todoObj){
state.todos.unshift(todoObj);
},
CHECK_TODO(state,id){
state.todos.forEach(todo => {
if(todo.id === id) todo.done = !todo.done;
})
},
DELETE_TODO(state,id){
state.todos = state.todos.filter(todo => todo.id !== id);
},
UPDATE_TODO(state,{id,title}){
state.todos.forEach(todo => {
if(todo.id === id) todo.title = title;
})
},
CHECK_ALL_TODO(state,done){
state.todos.forEach(todo => todo.done = done);
},
CLEAR_ALL_TODO_DONE(state){
state.todos = state.todos.filter(todo => !todo.done);
}
}
export default new Store({
state,
getters,
actions,
mutations
})
Item.vue(Item组件)
主要变更部分:新增元素<input type="text"/> 和<button>编辑</button> ,新增方法handleBlur() 和handleEdit() 。
<template>
<li>
<label>
<input type="checkbox" :checked="todo.done" @change="handleChange(todo.id)"/>
<span v-show="!todo.isEdit">{{todo.title}}</span>
<input type="text" v-show="todo.isEdit" :value="todo.title" @blur="handleBlur(todo,$event)" ref="inputTitle"/>
</label>
<button class="btn btn-danger" @click="handleClick(todo.id)">删除</button>
<button class="btn btn-edit" v-show="!todo.isEdit" @click="handleEdit(todo)">编辑</button>
</li>
</template>
<script>
import {mapMutations} from "vuex";
export default {
name:"Item",
props:["todo"],
methods:{
...mapMutations({
handleChange:"CHECK_TODO"
}),
handleClick(id){
if(confirm("确定删除吗?")){
this.$store.commit("DELETE_TODO",id);
}
},
handleEdit(todo){
if(todo.hasOwnProperty("isEdit")){
todo.isEdit = true;
}else{
this.$set(todo,"isEdit",true);
}
this.$nextTick(() => {
this.$refs.inputTitle.focus();
})
},
handleBlur(todo,event){
if(!event.target.value.trim()) return alert("输入不能为空!");
this.$store.commit("UPDATE_TODO",{id:todo.id,title:event.target.value});
todo.isEdit = false;
}
}
}
</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;
display: none;
margin-top: 3px;
}
li:before {
content: initial;
}
li:last-child {
border-bottom: none;
}
li:hover{
background: #eee;
}
li:hover button{
display: block;
}
</style>
|