要熟悉一个框架,需要弄清楚怎么做到组件间的相互通信,而todolist是一个用来练习组件间相互通信的很好的小demo
首先使用vue-cli搭建一个项目,具体参考我的另一篇博客vue-cli搭建vue项目
文件结构
todolist功能
记录todo内容,可增加和删除todo内容,并标记是否已完成
todolist小tip
在搭建todolist时,使用了下面的一些内容
1.$emit
在子组件中通过this.$emit来调用父组件中的方法,以对父组件中的变量进行修改,在这个小demo中,通过this.$emit调用了父组件中的addTodo和delete方法,实现了增加和删除的操作
2.uuid
导入了uuid这个包,使用里面的v4方法来实现随机生成id
代码
main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
App.vue
<template>
<div id="app">
<AddTodo @add-todo="addTodo"/>
<Todos v-bind:todoList="todoList" @delete="deleteTodo"/>
</div>
</template>
<script>
import Todos from './components/Todo/Todo.vue'
import AddTodo from './components/Todo/AddTodo.vue'
export default {
name: 'app',
components: {
Todos,
AddTodo
},
data(){
return{
todoList:[ // todo列表
{
id:1,
title:'todo 1',
completed:false
},
{
id:2,
title:'todo 2',
completed:false
}
]
}
},
methods:{
addTodo(todo){ // 对应于子组件的add-todo方法
this.todoList.unshift(todo)
},
deleteTodo(id){ // 对应子组件的delete方法
for(let i=0;i<this.todoList.length;i++){
if(this.todoList[i].id==id){
this.todoList.shift(this.todoList[i])
}
}
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Todo.vue
<template>
<div class="todoContent">
<h1 class="todoTitle">todoList</h1>
<div class="todoList" :key="todo.id" v-for="todo in todoList" :class="{'completed':todo.completed}">
<input type="checkbox" v-model="todo.completed">
{{todo.title}}
<button @click="$emit('delete',todo.id)">删除</button>
</div>
</div>
</template>
<script>
export default {
name:"Todos",
props:["todoList"] // 使用父组件的todoList变量
}
</script>
<style>
.todoTitle{
text-align: left;
}
.todoList{
text-align: left;
padding: 20px;
margin: 2px;
font-size: 20px;
color: #fff;
background-color: #333;
}
.completed{
text-decoration: line-through;
color: #f00;
}
</style>
AddTodo.vue
<template>
<div class="addTodo">
<input type="text" v-model="title">
<button @click="add">add</button>
</div>
</template>
<script>
import uuid from 'uuid' // 导入uuid
export default {
name:'addTodo',
data(){
return{
title:"" // 绑定的文本框的内容
}
},
methods:{
add(){
let todo={
id:uuid.v4(), // 随机生成的id
title:this.title,
completed:false
}
this.title="" // 将输入的内容重新设置为空
this.$emit('add-todo',todo) // 触发父组件的add-todo事件,todo作为参数传过去
}
}
}
</script>
<style>
.addTodo{
float: right;
outline: none;
}
</style>