vue---组件通讯
Posted czheng7
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue---组件通讯相关的知识,希望对你有一定的参考价值。
Vue的通信方式有几种?隔代组件的通信用哪种方式解决?
一:props/$emit
父传子:
// parent.vue
<s-child v-bind:infos="informations" /> // infos对应子组件上
data() {
return {
informations: [
{ name: "A1", age: 16 },
{ name: "A2", age: 17 },
{ name: "A3", age: 18 },
{ name: "A4", age: 19 },
]
}
}
// child.vue
// 子组件props接收,
...
props: ["infos"] // 接收父组件传递的参数 infos 一般不用[]接收
...
子传父 $emit
// 父组件 <s-child v-on:infos="cy" /> 与子组件infos事件保持一致 <div>{{msg}}</div> data() { msg: ‘‘ } methods: { cy(somedata) { this.msg = somedata } } // 子组件 <button v-on:click="onClick">向父组件传参</button> data() { return { childmsg: "我是子组件的值" } } methods: { onClick: function () { this.$emit(‘infos‘, this.childmsg) // infos是父组件绑定的事件,this.childmsg作为参数传过去 } }
二:$children/$parent
// parent <template> <div> <div> <div>{{ msg }}</div> <s-child></s-child> <button @click="changeA">点击改变子组件值</button> </div> </div> </template> <script> import Child from ‘./child‘ export default { name: ‘ThisParent‘, data() { return { // message: ‘hello‘ msg: ‘Welcome parents‘ } }, components: { "s-child": Child }, methods: { changeA() { // 获取到子组件A this.$children[0].messageA = ‘this is new value for parents‘ } } } </script>
// child <template> <div> <div class="com_a"> <span>{{ messageA }}</span> <p>获取父组件的值为:{{ parentVal }}</p> </div> </div> </template> <script> export default { data() { return { messageA: ‘this is old‘ } }, computed:{ parentVal() { return this.$parent.msg; } } } </script>
三:provide/inject
概念: provide
/ inject
是vue2.2.0
新增的api, 简单来说就是父组件中通过provide
来提供变量, 然后再子组件中通过inject
来注入变量。注意: 这里不论子组件嵌套有多深, 只要调用了inject
那么就可以注入provide
中的数据,而不局限于只能从当前父组件的props属性中回去数据
// A.vue <template> <div> <com-b></com-b> </div> </template> <script> import comB from ‘./B‘ export default { name: ‘A‘, provide: { for: "A里面的值" }, components: { comB } } </script>
// B.vue <template> <div> {{demo}} <com-c></com-c> </div> </template> <script> import comC from ‘./C‘ export default { name: ‘B‘, inject: [‘for‘], data() { return { demo: this.for } }, components: { comC } } </script>
// C.vue <template> <div> {{demo}} </div> </template> <script> export default { name: ‘C‘, inject: [‘for‘], data() { return { demo: this.for } } } </script>
# 四:ref/$refs
父组件如何直接调取子组件的数据和方法,而不是通过子组件传上来的.我们要理解父组件直接拿事件是在父组件上,子组件传上来数据,事件是在子组件上,是完全不同的两种情况
ref
:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据, 我们看一个ref
来访问组件的例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app-7"> <div> <to-child ref=‘ch‘></to-child> <h1 @click="onclick">我是父组件点击获取子组件信息</h1> </div> </div> </body> <script> Vue.component(‘to-child‘, { template: ‘<div>我是子组件</div>‘, data() { return { sonData: ‘我是子组件的数据‘ } }, methods: { sonMethod() { console.log(‘我是子组件的方法sonMethod‘) } } }) var app7 = new Vue({ el: ‘#app-7‘, data() { return { } }, methods: { onclick() { // 父组件可以通过$refs拿到子组件的对象 // 然后直接调用子组件里面methods方法和data数据 let chil = this.$refs.ch console.log(chil) // 子组件对象 console.log(chil.sonData) // 子组件数据 console.log(chil.sonMethod()) // 子组件的方法 } } }) </script> </html>
# 五:eventBus
EventBus又称为事件总线。在Vue中可以使用EventBus来作为组件传递数据的桥梁,就像是所有组件共用相同的事件中心,可以向该中心注册发送或者接收事件,所以组件都可以上下平行通知其它组件。但如果使用不慎,就会造成维护灾难。因此推荐更加强大的Vuex作为状态管理中心,将通知概念上升到共享状态层次。
使用 EventBus
初始化:
// 第一种方式:可以在main.js 中,初始化 EventBus Vue.prototype.$EventBus = new Vue() // 第二种方式:创建一个Bus.js ,再创建事件总线并将其导出,以便其它模板可以使用或者监听 // Bus.js import Vue from ‘vue‘ export const EventBus = new Vue(); // 你需要做的只是引入 Vue 并导出它的一个实例(在这种情况下,我称它为 EventBus )。 // 实质上它是一个不具备DOM的组件,它具有的仅仅只是它实例方法而已,因此它非常的轻便。
这样我们就创建了EventBus,接下来只需要在组件中加载它,并调用同一个方法。
发送和接收事件
和父子组件通信差不多,用 EventBus.$emit(‘emit事件名‘,数据)
发送, EventBus.$on("emit事件名", callback(payload1,…))
接受
// additionNum.vue 中发送事件 <template> <div> <button v-on:click="additionHandle">+加法</button> </div> </template> <script> import {EventBus} from ‘./bus.js‘ console.log(EventBus) export default { data() { return{ num: 1 } }, methods: { additionHandle() { EventBus.$emit(‘addition‘, { num: this.num++ }) } } } </script>
// showNum.vue 中接收事件 <template> <div> <div>计算和:{{count}}</div> </div> </template> <script> import {EventBus} from ‘./bus.js‘ export default { data() { return{ count: 0 } }, mounted() { EventBus.$on(‘addition‘, param => { this.count = param.num; }) } } </script>
如果只需要监听(接收)一次数据可以使用 EventBus.$once(‘事件名‘, callback(payload1,...)
移除事件监听者
EventBus.$off(‘事件名‘,回调函数)
-
EventBus.$off(‘事件名‘, callback)
,只移除这个回调的监听器。 -
EventBus.$off(‘事件名‘)
,移除该事件所有的监听器。 -
EventBus.$off()
, 移除所有的事件监听器,注意不需要添加任何参数。
// 导入我们刚刚创建的 EventBus import { EventBus } from ‘../Bus.js‘ // 事件监听函数 const clickHandler = function(clickCount) { console.log(`Oh, hello)`) } // 开始监听事件 EventBus.$on(‘i-got-clicked‘, clickHandler); // 停止监听 EventBus.$off(‘i-got-clicked‘, clickHandler);
# 六:Vuex
# 七:localStorage/sessionStorage
# 八:$attrs 与 $listeners
以上是关于vue---组件通讯的主要内容,如果未能解决你的问题,请参考以下文章