写点什么

Vue2.x 组件间通信汇总表

作者:小鑫同学
  • 2022-10-13
    北京
  • 本文字数:3231 字

    阅读完需:约 11 分钟

Vue2.x组件间通信汇总表

大家好,我是小鑫同学。一位从事过 Android 开发混合开发,现在长期从事前端开发的编程爱好者,我觉得在编程之路上最重要的是知识的分享,所谓三人行必有我师。所以我开始在社区持续输出我所了解到、学习到、工作中遇到的各种编程知识,欢迎有想法、有同感的伙伴加我fe-xiaoxin微信交流~


分享一篇以前做 Vue2.x 开发时总结的组件通信汇总

一、组件间通信方式表


接收数据: 对应组件调用$on;


派发数据: 对应组件调用$emit() || 4 | 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);}
复制代码




欢迎关注我的公众号“前端小鑫同学”,原创技术文章第一时间推送。

发布于: 刚刚阅读数: 3
用户头像

小鑫同学

关注

⚡InfoQ签约作者 2018-12-10 加入

还未添加个人简介

评论

发布
暂无评论
Vue2.x组件间通信汇总表_前端_小鑫同学_InfoQ写作社区