Vue组件之间的通信方式(个人理解)
1. props(父传子)
```
//父组件 parent.vue
<template>
//子组件
<child-com :num="num" :str="str" :obj="obj" :func="func" />
</tempalte>
//引入子组件
import ChildCom from './components/child';
export default{
components:{ChildCom},
data(){
return {
num:25,
str:'这是一个字符串类型的父组件传递的值',
obj:{
attr:'一个对象中的属性值'
}
}
},
methods:{
func(){
console.log('这是一个父组件的方法,可以由子组件通过props方式调用');
}
}
}
//子组件 child.vue
export default{
props:{
num:{
type:Number//num的类型为---数字类型
},
str:{
type:String,//str的类型为---字符串类型
default:'hello default value'//str的默认值
},
obj:{
type:Object,//obj的类型为---对象类型
reqired:true//是否必传的参数,布尔值true:必须传这个参数 ,默认为false:不是必传
},
func:{
type:Function, //func的类型为---函数
default(){ //不传递时默认值
return ()=>{}
}
}
},
data(){
return{}
},
mounted(){
console.log(this.num);
//控制台输出:25
console.log(this.str);
//控制台输出:这是一个字符串类型的父组件传递的值
console.log(this.obj);
//控制台输出:{attr:'一个对象中的属性值'}
this.func();
//调用parent的func方法
//控制台输出:这是一个父组件的方法,可以由子组件通过props方式调用
}
}
```
2. v-on/this.$emit('方法名','参数');(父传子,子通过调用父传来的方法回传参数)
```
//(父传子,子通过调用父传来的方法回传参数)
//父组件: @childMethod="parentMethod"
//子组件: this.$emit('方法名',参数)
//childMethod:child子组件中this.$emit('childMethod',参数)
//parentMethod:parent父组件中的要被子组件调用的方法名
//父组件 parent.vue
<template>
//子组件
<child-com :num="num" :str="str" :obj="obj" @func="func" />
</tempalte>
//引入子组件
import ChildCom from './components/child';
export default{
components:{ChildCom},
data(){
return {
num:25,
str:'这是一个字符串类型的父组件传递的值',
obj:{
attr:'一个对象中的属性值'
}
}
},
methods:{
func(arguments){
console.log('这是一个父组件的方法,可以由子组件通过props方式调用',arguments);
}
}
}
//子组件 child.vue
export default{
props:{
num:{
type:Number//num的类型为---数字类型
},
str:{
type:String,//str的类型为---字符串类型
default:'hello default value'//str的默认值
},
obj:{
type:Object,//obj的类型为---对象类型
reqired:true//是否必传的参数,布尔值true:必须传这个参数 ,默认为false:不是必传
}
},
data(){
return{}
},
mounted(){
console.log(this.num);
//控制台输出:25
console.log(this.str);
//控制台输出:这是一个字符串类型的父组件传递的值
console.log(this.obj);
//控制台输出:{attr:'一个对象中的属性值'}
this.$emit('func',参数);
//调用parent的func方法
//控制台输出:这是一个父组件的方法,可以由子组件通过props方式调用,参数
}
}
```
3. this.$refs.child.method(arguments);(父传子)
```
//child:为子组件ref注册的名字,可自行命名
//method:为子组件中的方法名
//父组件 parent.vue
<template>
//子组件
<child-com ref="child" />
</tempalte>
//引入子组件
import ChildCom from './components/child';
export default{
components:{ChildCom},
data(){
return{}
}
methods:{
func(){
this.$refs.child.childMethod();
//控制台输出:我是子组件的方法,父组件通过this.$refs.child.childMethod()调用
}
}
}
//子组件 child.vue
export default{
props:{},
data(){
return{}
},
mounted(){},
methods:{
childMethod(){
console.log('我是子组件的方法,父组件通过this.$refs.child.childMethod()调用');
}
}
}
```
4. this.$parent.$parent.func(arguments);(子传父)
```
//父组件的fun方法
//父组件 parent.vue
<template>
//子组件
<child-com />
</tempalte>
//引入子组件
import ChildCom from './components/child';
export default{
components:{ChildCom},
data(){
return {}
},
methods:{
func(arguments){
console.log('这是一个父组件的方法,可以由子组件通过this.$parent.$parent(参数)方式调用',arguments);
}
}
}
//子组件 child.vue
export default{
props:{ },
data(){
return{}
},
mounted(){
this.$parent.$parent.func('参数');
//调用parent的func方法
//控制台输出:这是一个父组件的方法,可以由子组件通过this.$parent.$parent(参数)方式调用,参数
}
}
```
5. this.$attrs:里面包含所有父组件中不作为 prop传递的属性。可以进行跨级的参数传递
```
//(父传子---属性)
//可修改this.$atrrs里的属性值
//父组件 parent.vue
<template>
<child-com str="这是一个不通过prop传递的字符串" :strProp="strProp" />
</template>
export default {
data(){
return {
strProp:"这是一个通过prop传递的字符串"
}
},
}
//子组件 child.vue
<tempalte>
<grand-child v-bind="$attrs" /> //针对向下级组件传递
</temaplate>
import GrandChildCom from './grandchild';
export default {
components:{GrandChildCom},
props:{
strProp:{
type:String,
default:''
}
},
data(){
return {}
},
mounted(){
console.log(this.$atrrs);//{str:'这是一个不通过prop传递的字符串'}
console.log(this.strProp);//这是一个通过prop传递的字符串
}
}
//孙子组件GrandChild.vue
export default {
props:{
strProp:{
type:String,
default:''
}
},
data(){
return {}
},
mounted(){
console.log(this.$atrrs);//{str:'这是一个不通过prop传递的字符串'}
console.log(this.strProp);//这是一个通过prop传递的字符串
}
}
```
6. this.$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器
```
//(父传子---方法,子通过调用父传来的方法回传参数)
//this.$listeners
//父组件 parent.vue
<template>
<child-com @handleUpdate="handleUpdate" @handleAdd.native="handleAdd" />
</template>
export default {
data(){
return {}
},
methods:{
handleUpdate(val){
console.log('这是handleUpdate的日志',val);
},
handleAdd(){
console.log('这是handleAdd的日志');
},
}
}
//子组件 child.vue
<tempalte>
<grand-child-com v-on="$listeners" /> //针对向下级组件传递
</temaplate>
import GrandChildCom from './grandchild';
export default {
components:{GrandChildCom},
props:{},
data(){
return {}
},
mounted(){
console.log(this.$listeners);//{handleUpdate:f}
console.log(this.$listeners.handleUpdate('child调用的'));//这是handleUpdate的日志,child调用的
}
}
//孙子组件GrandChild.vue
export default {
props:{
strProp:{
type:String,
default:''
}
},
data(){
return {}
},
mounted(){
console.log(this.$listeners);//{handleUpdate:f}
console.log(this.$listeners.handleUpdate('grandChild调用的'));//这是handleUpdate的日志,grandChild调用的
}
}
```
7. provide/inject(选项 / 组合):允许一个祖先组件向其所有子孙后代注入一个依赖,可以注入属性和方法,从而实现跨级父子组件通信
```
//(父传子---依赖,子通过调用父传来的方法回传参数)
// provide/inject
//父组件 parent.vue
<template>
<child-com />
</template>
export default {
data(){
return {
name:'Hello Xiaoer'
}
},
provide() {
return {
provideName: {
name: this.name,
change: (val) => {
console.log( val )
}
}
}
}
}
//子组件 child.vue
<tempalte>
<grand-child-com /> //针对向下级组件传递
</temaplate>
import GrandChildCom from './grandchild';
export default {
components:{GrandChildCom},
props:{},
data(){
return {}
},
inject: ['provideName'],
mounted(){
console.log(this.provideName.name);//控制台输出:Hello Xiaoer
this.provideName.change('变化函数');//控制台输出:变化函数
},
}
//孙子组件GrandChild.vue
export default {
props:{},
data(){
return {}
},
inject: ['provideName'],
mounted(){
console.log(this.provideName.name);//控制台输出:Hello Xiaoer
this.provideName.change('变化函数');//控制台输出:变化函数
},
}
```
8. EventBus:(第三方库)甚至任意2个组件间通信(任意组件)
```
[github地址](https://github.com/krasimir/EventBus)
//通过导出一个 Vue 实例,然后再需要的地方引入:
// eventBus.js
import Vue from 'vue'export
const EventBus = new Vue()
//使用 EventBus 订阅和发布消息:
import {EventBus} from '../utils/eventBus.js'
// 订阅消息(接受更新后需要做点什么的组件)
EventBus.$on('update', val => {})
// 发布消息(负责更新的组件)
EventBus.$emit('update', '更新信息')
```
```
//在main.js中初始化一个全局的事件:
// main.js
Vue.prototype.$eventBus = new Vue()
//index.vue
// 订阅消息(接受更新后需要做点什么的组件)
this.$eventBus.$on('update', val => {})
// 发布消息(负责更新的组件)
this.$eventBus.$emit('update', '更新信息')
```
```
//移除事件监听
this.$eventBus.$off('update', {})
```