vue组件之间通信方式

789 阅读1分钟

(1)props/ $emit/$on

父组件用props将属性传给子组件,子组件不会之间修改props传来的值,而是通过$emit发送一个event,并将需要的data发送给父组件,父组件内通过监听子组件上传来的event和data,进行相应的处理。

(2)$parent和$children

parent可以获得父组件的实例,\$children可以获得所有子组件实例,可以通过options.name进行过滤得到需要的实例

this.$children.filter(item=>{
    return item.$options.name==='some-name'
})

(3)中央事件总线 EventBus

适用于非父子组件之间的通信。全局定义一个vue实例。最简单的代码:

Vue.prototype.$bus = new Vue()

则在任一组件内都可以使用this.$bus.$emit发送事件,this.$bus.$emit监听事件 另外也可以做成一个插件,在beforeCreated时候将$bus插入到根节点,然后子组件从父组件获取$bus,这样每个组件也能使用$bus。这样的好处是,具有较好的可扩展性,目录结构:

eventBus/index.js:

import {install, Vue} from './install'

export default class eventBus {
  constructor() {
    this._event = null
    this.init()
  }

  init() {
    this._event = new Vue()
  }

  destroy() {
    this._event.$destroy()
  }
}
eventBus.install = install

eventBus/install.js:

export let Vue
import eventBus from './index'

export function install(vue_) {
  Vue = vue_
  if (!!install.installed) {
    console.log('$event 已安装')
    return
  }
  install.installed = true  // 单例 已安装
  let bus = new eventBus()
  Vue.mixin({
    beforeCreate() {
      if (!this._busRoot) {
        this._busRoot = this
        this._busRoot._bus = bus
      } else {
        this._busRoot = this.$parent && this.$parent._busRoot || this
      }
    },
    destroyed() {
      this._busRoot._bus.destroy()
    }
  })
  Object.defineProperty(Vue.prototype, '$bus', {
    get() {
      return this._busRoot._bus._event
    }
  })
}

main.js中引入代码:

import eventBus from './eventbus'
Vue.use(eventBus)

(4)provide/inject

适用于父子组件之间,借鉴于react。这种方法有一个弊端,传入的值默认不是双向绑定的,也就是说父组件修改,子组件不知道,有对应的解决办法,这里略。

父组件provide共享数据:

provide() {
  return {
    user: this.user,
  }
},

子组件inject数据:

inject: {
      user: 'user'
},

(5)VUEX

vuex可以管理非常复杂的states,相当于前端的数据库,具体这里略了,有时间会新起一片,专门讲解VUEX。