Vue 组件通信
- 前言
- 一、父组件与子组件通信
- 二、子组件与父组件通信
- 三、其他组件通信
前言
Vue 是单页面应用,页面与页面之间,功能与功能之间,都是一个个的组件构成。组件也有层级结构,父与子关系,子与父关系,兄弟关系等。那么有关系的组件之间如何通信?将是本文探讨的主题。
一、父组件与子组件通信
父组件向子组件传值直接通过属性的方式,子组件通过 props 接收。
父组件调用子组件方法是通过给子组件绑定 ref 获取子组件实例。随后找到子组件的方法并调用。
父组件 TodoList.vue
<template>
<div>
<div>
<input type="text" v-model="text"><button @click="add">添加待办</button>
<todo-item
:taskList="taskList"
ref="item"
/>
<button @click="del">删除包含完成的事项</button>
</div>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
name: 'TodoList',
data () {
return {
text:"",
taskList:[]
}
},
components: {
'todo-item': TodoItem,
},
methods: {
add(){
this.taskList.push({text:this.text})
},
del(){
//通过ref绑定子组件实例,直接调用其方法
this.taskList = this.$refs.item.del(this.taskList,'完成');
}
}
}
</script>
子组件 TodoItem.vue
<template>
<div>
<div v-for="(item,index) in taskList">
<span>{{item.text}}</span>
</div>
</div>
</template>
<script>
export default {
name: 'TodoItem',
props:['taskList'],
methods: {
//子组件方法,供父组件调用
del(arr,str){
return arr.filter((item)=>item.text.indexOf(str)<0)
}
}
}
</script>
二、子组件与父组件通信
子组件与父组件通信有 2 种方法。
- 子组件通过 props 获取父组件的方法,并向父组件传参。
父组件 TodoList.vue
<template>
<div>
<div>
<button @click="show">显示列表</button>
<todo-item
:taskList="taskList"
:isShow="isShow"
:del="del"
/>
<div>{{tip}}</div>
</div>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
name: 'TodoList',
data () {
return {
isShow:false,
tip:'未删除',
taskList:[{text:"完成国际会议",done:true},{text:"还未开始国内会议",done:false}]
}
},
components: {
'todo-item': TodoItem,
},
methods: {
show(){
this.isShow = !this.isShow
},
del(str){
this.tip = str;
//通过ref绑定子组件,直接调用其方法
this.taskList = this.taskList.filter((item)=>item.done)
}
}
}
</script>
子组件 TodoItem.vue
<template>
<div v-if="isShow">
<div v-for="(item,index) in taskList" >
<span>{{item.text}}</span>
</div>
<button @click="del('删除成功')">删除完成的事项</button>
</div>
</template>
<script>
export default {
name: 'TodoItem',
props:['taskList','isShow','del']
}
</script>
- 子组件通过触发 $emit 调取父组件的方法,并向父组件传参。
父组件 TodoList.vue
<template>
<div>
<div>
<button @click="show">显示列表</button>
<todo-item
:taskList="taskList"
:isShow="isShow"
@on-all="del"
/>
<div>{{tip}}</div>
</div>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
name: 'TodoList',
data () {
return {
isShow:false,
tip:'未删除',
taskList:[{text:"完成国际会议",done:true},{text:"还未开始国内会议",done:false}]
}
},
components: {
'todo-item': TodoItem,
},
methods: {
show(){
this.isShow = !this.isShow
},
del(str){
this.tip = str;
//通过ref绑定子组件,直接调用其方法
this.taskList = this.taskList.filter((item)=>item.done)
}
}
}
</script>
子组件 TodoItem.vue
<template>
<div v-if="isShow">
<div v-for="(item,index) in taskList" >
<span>{{item.text}}</span>
</div>
<button @click="del">删除完成的事项</button>
</div>
</template>
<script>
export default {
name: 'TodoItem',
props:['taskList','isShow'],
methods: {
//通过$emit触发父组件方法,给父组件传参
del(){
this.$emit('on-all','删除成功');
}
}
}
</script>
- 区别
通过 props 方式简写:
Father 组件
<template>
<div>
<son :del="del">
</div>
<template>
export default {
name: 'Father',
method:{
del(){
console.log("这是父组件的方法");
}
}
}
Son 组件
<template>
<div @click = "del"></div>
<template>
export default {
name: 'Son',
props:['del'],
}
通过 $emit 方式简写:
Father 组件
<template>
<div>
<son @on-del="del">
</div>
<template>
export default {
name: 'Father',
method:{
del(){
console.log("这是父组件的方法");
}
}
}
Son 组件
<template>
<div @click = "$emit('on-del')"></div>
<template>
export default {
name: 'Son',
}
三、其他组件通信
其他组件通信可使用 Vuex 状态管理工具。其核心思想是将所有状态集中管理,一处有变动。其他地方同步更新。