vue组件间的通信方式
组件化的目的:复用性强,可维护性高,提升开发效率,方便单元测试
一,props
这是vue父组件向子组件传参最常用的方式
//parent
<template> <div> <child name="child"></child> </div> </template> <script> import child from './child.vue' export default { name: 'parent', data () { return { } }, components:{ child } } </script>
//child <template> <div> 我是{{name}}子组件 </div> </template> <script> export default { props:{ name: { type: String, default: 'child' }, } } </script>
二,emit
子组件通过$emit发布事件,子组件在父组件中通过v-on订阅事件
//child <template> <div> <button @click="sentMsg">点击向父组件传参</button> </div> </template> <script> export default { methods:{ sentMsg(){ this.$emit('onMsg','子组件传来的信息') } } }
// parent <template> <div> <child name="child" @onMsg="onMsg"></child> </div> </template> <script> import child from './child.vue' export default { name: 'parent', data () { return { } }, components:{ child }, methods:{ onMsg(val){ console.log(val) } } }
三,Event Bus
通过创建一个vue的实例作为中央事件总线,用它来发布和订阅事件,实现父子,兄弟,跨级等组件间的通信。
第一步:创建一个新的bus.js文件,创建一个新的vue实例
import Vue from 'Vue' export default new Vue
第二步:通过$emit发布事件,传递参数
bus.$emit('eventbus','通过eventbus实现子组件传来的信息')
第三步:通过$on订阅事件,接受参数
bus.$on('eventbus',val=>{
console.log(val)
})
第四步:清除事件总线
beforeDestroy(){ bus.$off('eventbus') }
eventBus实现原理:
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(item => { item(args) }); } } $off(name,fn){ if(this.callbacks[name].indexOf(fn) != -1){ this.callbacks[name].splice(this.callbacks[name].indexOf(fn), 1) } } }
四,vuex
vuex是vue的状态管理器,Vuex 实现了一个单向数据流,在全局拥有一个 State 存放数据,当组件要更改 State 中的数据时,必须通过 Mutation 进行,Mutation 同时提供了订阅者模式供外部插件调用获取 State 数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走 Action,但 Action 也是无法直接修改 State 的,还是需要通过 Mutation 来修改 State 的数据。最后,根据 State 的变化,渲染到视图上。

vue components: vue组件,通过$store.dispatch('action名',data)触发actions中的某一个action通过commit('mutation名',data)触发moutations实现state改变;
getters:state 对象读取方法。图中没有单独列出该模块,应该被包含在了 render 中,Vue Components 通过该方法读取全局 state 对象。
五,$attrs 和 ¥listeners
多级组件嵌套需要传递数据时,通常使用的方法是通过 vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此 Vue2.4 版本提供了另一种方法----$attrs/$listeners
$attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用。$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件
六,provide/inject
Vue2.2.0 新增 API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。
provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
七,$parent/$children/$refs/$root
浙公网安备 33010602011771号