3.3 在数据接发送方触发事件
在数据发送方,调用 bus.emit(‘事件名称’, 要发送的数据) 方法触发自定义事件。
<template> <h3>Bro1 数据发送方</h3> <div>Bro1 内的数据: {{ bro1msg }}</div> <button @click="send"> 发送数据 </button> </template> <script> // 导入eventBus模块的,得到bus对象 import bus from './eventBus.js' export default { name: 'Bro1', data() { return { bro1msg: 'bro1msg数据' } }, methods: { send() { // 发送数据 bus.emit( 'broSendMsg', this.bro1msg ) } } } </script> <style> </style>
3.4 在数据接收方自定义事件
在数据接收方,调用 bus.on(‘事件名称’, 事件处理函数) 方法注册一个自定义事件。
<template> <h3>Bro2 数据接收方</h3> <div>获得的数据: {{ msg }}</div> </template> <script> // 导入eventBus模块的,得到bus对象 import bus from './eventBus.js' export default { name: 'Bro2', data() { return { msg: '' } }, created() { // bus.on 方法注册一个自定义事件,通过事件的处理函数形参接收数据 bus.on( 'broSendMsg', (val)=>{ this.msg = val } ) } } </script> <style> </style>
4 后代关系组件之间的数据共享
后代关系组件之间共享数据,指的是父节点的组件向其子孙组件共享数据。此时组件之间的嵌套关系比较复杂,可以使用 provide 和 inject 实现后代关系组件之间的数据共享。
4.1 父节点通过 provide 共享数据
父节点的组件可以通过 provide 方法,对其子孙组件共享数据。
<template> <div> <h1>App 组件</h1> <div> color: {{color}} </div> <hr> <Son></Son> </div> </template> <script> import Son from './son.vue' export default { name: 'App', data() { return { color: 'red' } }, // provide 函数return的对象中包含了要向子孙组件共享的数据 provide() { return { color: this.color } }, components: { Son } } </script> <style> </style>
4.2 子孙节点通过 inject 接收数据
子孙节点可以使用 inject 数组,接收父级节点向下共享的数据。
<template> <div> <h3>Son 组件</h3> <div> son_count: {{color}} </div> <hr> <Grandson></Grandson> </div> </template> <script> import Grandson from './Grandson.vue' export default { name: 'Son', // 子孙组件使用 inject 接收父组件共享的数据 inject: ['color'], components: { Grandson } } </script> <style> </style>
<template> <div> <h3>Grandson 组件</h3> <div> Grandson_count: {{ color }} </div> </div> </template> <script> export default { name: 'Grandson', // 子孙组件使用 inject 接收父组件共享的数据 inject: ['color'], } </script> <style> </style>
4.3 父节点对外共享响应式的数据
父节点使用 provide 向下共享数据时,可以结合 computed 函数向下共享响应式的数据。
<template> <div> <h1>App 组件</h1> <div> color: {{color}} </div> <div>count: {{ count }}</div> <button @click="add"> +1 </button> <hr> <Son></Son> </div> </template> <script> // 从vue中按需导入computed函数 import { computed } from 'vue' import Son from './son.vue' export default { name: 'App', data() { return { count: 0, color: 'red' } }, methods: { add() { this.count++ } }, // provide 函数return的对象中包含了要向子孙组件共享的数据 provide() { return { // 使用 computed 函数,把共享数据包装为响应式数据 count: computed( ()=>this.count ), color: this.color } }, components: { Son } } </script> <style> </style>
4.4 子孙节点使用响应式的数据
如果父级节点共享的是响应式的数据,则子孙节点必须以 .value 的形式进行使用。
<template> <div> <h3>Son 组件</h3> <div> son_count: {{color}} </div> <div> son_count: {{count.value}} </div> <hr> <Grandson></Grandson> </div> </template> <script> import Grandson from './Grandson.vue' export default { name: 'Son', // 子孙组件使用 inject 接收父组件共享的数据 inject: ['color', 'count'], components: { Grandson } } </script> <style> </style>
<template> <div> <h3>Grandson 组件</h3> <div> Grandson_count: {{ color }} </div> <div> Grandson_count: {{count.value}} </div> </div> </template> <script> export default { name: 'Grandson', // 子孙组件使用 inject 接收父组件共享的数据 inject: ['color', 'count'], } </script> <style> </style>
5 vuex
vuex 是终极的组件之间的数据共享方案。在企业级的 vue 项目开发中,vuex 可以让组件之间的数据共变得高 效、清晰、且易于维护。
vuex将要共享的数据存放于一个区域,要使用共享数据的组件,直接引入。
6 总结
1.父子关系
① 父 -> 子 属性绑定
② 子 -> 父 事件绑定
③ 父 <-> 子 组件上的 v-model
2.兄弟关系
④ EventBus
3.后代关系
⑤ provide & inject
4.全局数据共享
⑥ vuex