一、使用的方法和组件:
v-on 绑定自定义事件
$on 监听事件
$emit 触发事件
@add 自定义方法
this.$on() 绑定监听
this.$refs.hared()找到组件
二、实例代码
方式一: 适合 A-B(单层级传递)
TodoHeader.vue
<div class="todo-header">
<input type="text" v-model="title" @keyup.enter="add" placeholder="请输入你的任务名称,按回车键确认"/>
export default {
name:'TOdoHeader',
props: ['addTodoList'],
data () {
return {
title:''
}
},
created () {
},
methods: {
add () {
const title =this.title.trim()
if (!title) {
alert('请输入任务名称')
return
}
const todo = {
title,
isShow:false
}
this.$emit('addTodoList', todo)
this.title =''
}
}
}
<style scoped>
.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);
}
App.vue
<div class="todo-container">
<div class="todo-wrap">
<TodoHeader @addTodoList="addTodoList"/>
<TodoList :todoList="todoList" :deleteItem="deleteItem"/>
<TodoFooter :todoList="todoList" :deleteAll="deleteAll" :selectAll="selectAll"/>
import TodoHeaderfrom './components/TodoHeader'
import TodoFooterfrom './components/TodoFooter'
import TodoListfrom './components/TodoList'
export default {
name:'App',
data () {
return {
todoList: JSON.parse(window.localStorage.getItem('todo_key') ||'[]')
}
},
components: {
TodoHeader,
TodoFooter,
TodoList
},
created () {
},
watch: {
todoList: {
deep:true,
handler:function (value) {
window.localStorage.setItem('todo_key', JSON.stringify(value))
}
}
},
methods: {
addTodoList (list) {
this.todoList.unshift(list)
},
deleteItem (index) {
this.todoList.splice(index, 1)
},
deleteAll () {
this.todoList =this.todoList.filter(todoList => !todoList.isShow)
},
selectAll (check) {
this.todoList.forEach(todoList => {
todoList.isShow = check
})
}
}
}
<style scoped>
.todo-container {
width:600px;
margin:0 auto;
}
.todo-container .todo-wrap {
padding:10px;
border:1px solid #ddd;
border-radius:5px;
}
方式二:适合A-B-C(多层级传递)
App.vue
<div class="todo-container">
<div class="todo-wrap">
<TodoHeader ref="harnd"/>
<TodoList :todoList="todoList" :deleteItem="deleteItem"/>
<TodoFooter :todoList="todoList" :deleteAll="deleteAll" :selectAll="selectAll"/>
import TodoHeaderfrom './components/TodoHeader'
import TodoFooterfrom './components/TodoFooter'
import TodoListfrom './components/TodoList'
export default {
name:'App',
data () {
return {
todoList: JSON.parse(window.localStorage.getItem('todo_key') ||'[]')
}
},
components: {
TodoHeader,
TodoFooter,
TodoList
},
created () {
},
watch: {
todoList: {
deep:true,
handler:function (value) {
window.localStorage.setItem('todo_key', JSON.stringify(value))
}
}
},
mounted () {
this.$refs.harnd.$on('addTodoList', this.addTodoList)
},
methods: {
addTodoList (list) {
this.todoList.unshift(list)
},
deleteItem (index) {
this.todoList.splice(index, 1)
},
deleteAll () {
this.todoList =this.todoList.filter(todoList => !todoList.isShow)
},
selectAll (check) {
this.todoList.forEach(todoList => {
todoList.isShow = check
})
}
}
}
<style scoped>
.todo-container {
width:600px;
margin:0 auto;
}
.todo-container .todo-wrap {
padding:10px;
border:1px solid #ddd;
border-radius:5px;
}
TodoFooter.vue
<div class="todo-header">
<input type="text" v-model="title" @keyup.enter="add" placeholder="请输入你的任务名称,按回车键确认"/>
export default {
name:'TOdoHeader',
props: ['addTodoList'],
data () {
return {
title:''
}
},
created () {
},
methods: {
add () {
const title =this.title.trim()
if (!title) {
alert('请输入任务名称')
return
}
const todo = {
title,
isShow:false
}
this.$emit('addTodoList', todo)
this.title =''
}
}
}
<style scoped>
.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);
}