大家好,我是小鑫同学。一位从事过 Android 开发、混合开发,现在长期从事前端开发的编程爱好者,我觉得在编程之路上最重要的是知识的分享,所谓三人行必有我师。所以我开始在社区持续输出我所了解到、学习到、工作中遇到的各种编程知识,欢迎有想法、有同感的伙伴加我fe-xiaoxin微信交流~
分享一篇以前做 Vue2.x 开发时总结的组件通信汇总
一、组件间通信方式表
接收数据: 对应组件调用$on;
派发数据: 对应组件调用$emit() || 4 | refs∣父子组件通信∣√∣通过refs 获取子节点引用直接操作 || 5 | vuex | 兄弟组件通信
跨层级组件通信 | × | 通过单独文章说明 vuex 的使用 || 6 | $root | 兄弟组件通信 | √ | 接收数据: 对应组件调用根组件的$on()
派发数据: 对应组件调用根组件的$emit() || 7 | $parent | 父子组件通信
兄弟组件通信 | √ | 接收数据: 对应组件调用公共父组件的$on()
派发数据: 对应组件调用公共父组件的$emit() || 8 | $children | 父子组件通信 | √ | 通过$children获取并查找指定子节点后直接操作 || 9 | provide/inject | 跨多层级组件通信 | √ | 接收数据: "孙"辈组件通过定义inject获取数据
派发数据: 父组件中通过定义provide设置数据 || 10 | $attrs | 父=>孙
(非属性特性传参) | √ | 场景 1
父孙传参
接收数据: 孙辈组件中props定义接收
桥接数据: 子组件中通过v-bind="$attrs"展开
派发数据: 父组件中绑定数据进行派发
场景 2
父子传参
接收数据: 子组件中$attrs.xxx获取数据
派发数据: 父组件中绑定数据进行派发 || 11 | $listeners | 孙=>父
(事件传参) | √ | 场景 1
孙父传参
接收数据: 父组件调用$on/v-on
桥接数据: 子组件中通过v-bind="$listeners"展开
派发数据: 子组件调用$listeners.xxx()
场景 2
子父传参
接收数据: 父组件调用$on/v-on
派发数据: 子组件调用$listeners.xxx() |
二、组件间通信演示
1. props
父组件定义数据代码:
<Child :msg="data"/>
data() { return { data: 'Welcome to Your Vue.js App' }}
复制代码
子组件定义 props 接收数据代码
<h1>{{ msg }}</h1>
props: { msg: { type: String, default: '' },}
复制代码
2. emit&$on
子组件派发事件代码
<button @click="sendDataToParent">发送</button>
methods: { sendDataToParent() { this.$emit("send", "我是子组件"); },}
复制代码
父组件绑定事件代码 v1
<Child @send="childSend($event)" />
methods: { childSend(value) { console.log('value :>> ', value); }}
复制代码
父组件绑定事件代码 v2
<Child ref="child1" />
mounted() { this.$refs.child1.$on("send", (value) => { console.log("parent received value is :>> ", value); });}
复制代码
3. eventbus
自定义 bus 代码:
/* eslint-disable no-unused-vars */class Bus { constructor() { this.callbacks = {} }
on(name, fn) { this.callbacks[name] = this.callbacks[name] || [] this.callbacks[name].push(fn) }
emit(name,args){ if(this.callbacks[name]){ this.callbacks[name].forEach(callback => { callback(args) }); } }}module.exports = Bus
复制代码
子组件 1 发送数据代码:
<button @click="send">发送</button>
<script>export default { name: "Child", methods: { send() { this.$bus.emit("send", "我是子组件1"); }, },};</script>
复制代码
子组件 2 接收数据代码:
export default { name: "Child2", mounted() { this.$bus.on("send", (value) => { console.log("value :>> ", value); }); },};
复制代码
公共父组件代码:
<template> <div> <Child /> <Child2 /> </div></template>
复制代码
4. $refs
父组件调用子组件函数/设置数据/获取数据代码:
<Child ref="child1" />
mounted() { // ** 注意组件挂载顺序 // 获取子组件data数据 console.log("this.$refs.child1.msg :>> ", this.$refs.child1.msg); // 修改子组件data数据 this.$refs.child1.msg = "parent modify data"; // 调用子组件函数 this.$refs.child1.console("hello");}
复制代码
子组件代码:
<template> <div ref="c1" class="hello"> {{ msg }} </div></template>
<script>export default { name: "Child", data() { return { msg: "I'm child.", }; }, mounted() { console.log("child msg :>> ", this.msg); }, methods: { console(value) { console.log("parent value is :>> ", value); }, },};</script>
复制代码
5. $parent
子组件 1 通过 $parent 发送数据代码:
<button @click="sendDataToChild2">发送</button>
methods: { sendDataToChild2() { this.$parent.$emit("send", "我是子组件1"); },}
复制代码
子组件 2 通过 $parent 接收数据代码:
mounted () { this.$parent.$on('send',(value)=>{ console.log('child2 received value is :>> ', value); })}
复制代码
公共父组件代码:
<template> <div ref="app"> <Child /> <Child2 /> </div></template>
复制代码
6. $children
父组件调用子组件函数/设置数据/获取数据代码:
<Child ref="child1" />
mounted () { console.log('this.$children :>> ', this.$children); const children = this.$children[0] if(children.$vnode.data.ref === "child1"){ console.log('children.msg :>> ', children.msg); children.message('hello') }}
复制代码
子组件代码:
<template> <div ref="c1" class="hello"> </div></template>
<script>export default { name: "Child", data() { return { msg: "hello vue", }; }, methods: { message(value) { console.log("value :>> ", value); }, },};</script>
复制代码
7. root(同 root(同 root(同 parent)
// 发送修改为this.$root.$emit("send", "我是子组件1");
// 接收修改为this.$root.$on('send',(value)=>{ console.log('child2 received value is :>> ', value);})
复制代码
8. provide&inject
父组件设置 provide 代码
<Child />
export default { provide() { return { msg: "hello vue" }; }, components: { Child, },};
复制代码
子组件配置孙辈组件代码
<Grandson></Grandson>
export default { components: { Grandson, },};
复制代码
孙辈组件通过 inject 获取数据代码
export default { inject: ['msg'],};
复制代码
9. $attrs 属性传参
案例 1(父=>子传参):
1. 父组件传递数据代码:
<Child value="Hello Vue" />
复制代码
2. 子组件接收数据代码:
<!--非属性特性-为在props中定义--><div>{{$attrs.value}}</div>
复制代码
案例 2(父=>孙传参,子桥接):
1. 父组件传递数据代码:
<Child value="Hello Vue" />
复制代码
2. 子组件桥接属性代码:
<!--非属性特性-为在props中定义--><!--利用$attrs展开语法跨层级多参数传递--><Grandson v-bind="$attrs"></Grandson>
复制代码
3. 孙辈组件通过 props 属性接收数据代码:
<div>{{ value }}</div>
props: { value: { type: String, default: "", },},
复制代码
10. $listeners 事件传参
案例 1(子=>父传参)
1. 子组件派发事件代码:
<button @click="send">发送</button>
send() { this.$listeners.event('hello vue')}
复制代码
3. 父组件绑定事件接收数据代码:
<Child @event="message" /> message(value) { console.log('value :>> ', value);}
复制代码
案例 2(孙=>父传参,子桥接)
1. 孙辈组件派发事件代码:
<button @click="send">发送</button>
this.$emit("event", "hello vue");
复制代码
2. 子组件桥接事件代码:
<!--利用$listeners展开语法跨层级多参数传递--><Grandson v-on="$listeners"></Grandson>
复制代码
3. 父组件绑定事件接收数据代码:
<Child @event="message" /> message(value) { console.log('value :>> ', value);}
复制代码
欢迎关注我的公众号“前端小鑫同学”,原创技术文章第一时间推送。
评论