实战 Vue 之实现 todoList
todoList 案例功能说明
todoList 是一个任务管理功能,本文将使用 Vue 框架实现。包含的具体功能点如下:
- 添加任务;
- 修改任务状态;
- 删除任务;
- 筛选任务。
实现思路
一共分为三个组件实现该功能。
其中 TodoList.vue 为核心组件父组件,储存所有的状态,并分别提供添加任务、修改任务、删除任务以及筛选任务的方法。
TodoItem.vue 为任务项组件,渲染任务项视图,调父组件的修改任务状态方法和删除任务方法。
Filter.vue 为过滤器组件,渲染过滤项视图。调父组件的筛选任务方法。
TodoList.vue
<template>
<div class="hello">
<input type="text" v-model="text"><button @click="add">添加任务</button>
<div >
<todo-item :item="item" :filter ="filterFlag" @on-change="changeState(item)" @on-del="del(index)" v-for="(item,index) in taskList" :key="index"/>
</div>
<div class="list-mt-20">
<el-filter :item="item" v-for="(item,index) in statusList" :key="index" @on-filter="filter(item.flag)"/>
</div>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
import Filter from './Filter.vue';
export default {
name: 'TodoLit',
data(){
return{
taskList: [],
text:"",
filterFlag:'all',
statusList:[
{label:"全部",flag:'all'},
{label:"已完成",flag:'completed'},
{label:"未完成",flag:'uncompleted'}
]
}
},
components:{
'todo-item':TodoItem,
'el-filter':Filter
},
methods:{
//添加任务
add(){
this.taskList.push({text:this.text,done:false})
},
//改变任务状态
changeState(item){
item.done = !item.done;
},
//删除任务
del(index){
this.taskList.splice(index,1)
},
//过滤任务列表
filter(flag){
this.filterFlag = flag;
}
}
}
</script>
<style scoped>
.list-mt-20{
margin-top: 20px;
}
</style>
TodoItem.vue
<template>
<div :class="item.done?'todo-line':''" @click="changeStatus" v-if="show(item)">
<span>{{item.text}}</span><button @click="del">删除</button>
</div>
</template>
<script>
export default {
name: 'TodoItem',
props: ['item','filter'],
computed:{
//过滤任务是否显示
show(){
return item=>{
if(this.filter == 'all'){
return true
}else{
if(this.filter == 'completed'){
if(item.done){
return true
}else{
return false
}
}else{
if(!item.done){
return true
}else{
return false
}
}
}
}
}
},
methods:{
//修改任务状态
changeStatus(){
this.$emit('on-change')
},
//删除任务
del(){
this.$emit('on-del')
}
}
}
</script>
<style scoped>
.todo-line{
text-decoration: line-through;
}
</style>
Filter.vue
<template>
<span class="filter-ml-20" @click="filter" >
{{item.label}}
</span>
</template>
<script>
export default {
name: 'Filter',
props: ['item'],
methods:{
//过滤任务列表
filter(){
this.$emit('on-filter')
}
}
}
</script>
<style scoped>
.filter-ml-20{
margin-left: 20px;
}
</style>