vue中的组件通讯是必不可少的使用场景,回顾了平时使用vue中碰到的一些业务场景和对应采用的组件通讯方式,简单地作了一个归类总结,大体有如下一些通讯方式:vue
最经常使用的父子组件通讯方式,父组件经过props向子组件传值,子组件经过$emit事件向父组件触发事件并传值vuex
//父组件 <parent :name="xxx" @updateFromChild="xxx"></parent> //子组件 props: { name: { type: String, default: '' } } methods: { xxx () { this.$emit('updateFromChild', xx) } }
子组件中获取除了在props中定义以外的父组件中传递的属性值(class 和 style 除外)数组
//父组件 <parent name="小明" age=5 sex="男" home="杭州" class="parent"></parent> //子组件 <script> props: { name: { type: String, default: '' } } mounted () { console.log(this.$attrs) // {age:5, sex:"男", home:"杭州"} } </script>
当孙组件中须要用到爷组件中的大量属性,可是父组件却不须要用到不少,只是做为一个中转的传递,巧用$attrs能够节省在父组件中写的props值。dom
//父组件 <parent name="小明" age=5 sex="男" home="杭州" class="parent"></parent> //子组件 <template> <grand-son :passAttr="$attrs"></grand-son> </template> props: { name: { type: String, default: '' } }
包含了父做用域中的 (不含 .native 修饰器的) v-on 事件监听器。ide
//父组件 <parent @change="onChange" @hide="OnHide"></parent> //子组件 <script> mounted () { console.log(this.$listener) // {change:f, hide:f} } </script>
子组件中调用父组件的方法函数
是一个对象或返回一个对象的函数。该对象包含可注入其子孙的属性ui
是一个数组或者对象,包含祖先组件中注入的属性this
//父组件: <script> provide: { name: '小明', sayName () { console.log('我是' + this.name) } } mounted() { this.name = '小花' } </script> //子组件 <script> inject:['name', 'sayName'], mounted () { console.log(this.name); //小明 this.sayName() //我是小明 } </script>
能够看到在子组件中的 mounted 中打印出了 inject 中传递进来的 name 属性,并成功执行了 sayName 方法。并且 name 属性值仍是'小明',并无变成'小花',并非响应式的。code
已建立的实例的父实例和子实例中,子实例能够用 this.\$parent 访问父实例,子实例被推入父实例的 \$children 数组中,父实例能够用 this.$children 访问子实例。对象
//父组件 mounted(){ console.log(this.$children) //能够操做子组件的data,或者调用其methods中的方法 } //子组件 mounted(){ console.log(this.$parent) //能够拿到父组件中的属性和方法 }
一个对象,持有注册过 ref attribute 的全部 DOM 元素和组件实例。经过this.$refs.xxx 能够拿到 xxx 子组件中的data和methods。
//父组件 <child ref="child"></child> mounted(){ this.$refs.child.sayHello() // hello } //子组件 methods: { sayHello () { console.log('hello') } }
经过 this.$refs.xxx 进行对子组件的属性操做并非响应式的,所以避免在computed中进行使用。这是一个很好的应急手段,经常使用于如下两种使用场景
很少说,强大的复杂单页面全局数据通讯管理中心,供页面中的每一个组件进行全局数据的操做,并响应式到各个组件中。若是不知道自行搜索。这里就简单说两个注意点
对于非父子组件来讲,能够采用一个中间介质来做为一个中央事件总线,完成事件的触发和监听,并进行传值。
第一步:建立事件总线:创建一个eventBus.js文件
//仅仅是为了建立一个vue实例 import Vue from 'vue' export default new Vue()
第二步:在传值的源头组件中引进事件总线,进行事件的触发和传值
<template> <div class = "source"> <button @click="emitEvent"> </div> </template> <script> import eventBus from './eventBus.js' export default { methods: { emitEvent: funciton () { eventBus.$emit('sendVal',param) } } } </script>
第三步:在传值的目标组件中引进事件总线,进行事件的监听和传值的接收
<template> </template> <script> import eventBus from './eventBus.js' export default { data: function () { return { requireVal: '' } } mounted: function () { var that = this eventBus.$on('sendVal',function(val){ that.requireVal = val }) } } </script>
总结以下:
1.建立一个事件总线,例如demo中的eventBus,用它做为通讯桥梁
2.在须要传值的组件中用bus.$emit触发一个自定义事件,并传递参数
3.在须要接收数据的组件中用bus.$on监听自定义事件,并在回调函数中处理传递过来的参数