在我日常的开发中,不少问题都是见招拆招,遇到了便去解决。久而久之,出现了一个大问题,就是会反复的碰到这个问题,而反复去解决,由于上次解决的方式不必定能记到。就像你看你几个月前的代码,都以为:卧槽,谁的代码,这么烂。因此,最好的方式就是总结,不断总结。vue
Vue
的简便之处便在于组件,组件之间的复用让Vue
项目维护起来十分简便。而其中组件之间的通讯就是重中之重,无论哪个项目都有组件之间的通讯。而针对不一样状况下的组件之间通讯又各不相同,简直五花八门。像最基础的props
和@emit
父子组件通讯,大型项目官方推荐的Vuex
全局状态管理,小型项目试用的Bus
通讯等等,接下来我就总结出几种剑走偏锋的几种组件通讯。api
Vue
官方
api 中的,经过
$parent
和
$children
就能够访问组件的实例,拿到实例表明什么?表明能够访问此组件的一切方法和
data
。虽然官方说节制的使用,可是我仍是选择了无视。接下来就该思考下怎么去拿到指定组件的实例。
这应该是个通用的方法,原理就是经过不断遍历找到符合标准的组件实例,经过拿到的组件实例来拿到该实例的方法和data
数组
要注意边界状况,如在
#app
上拿$parent
获得的是new Vue()
的实例,在这实例上再拿$parent
获得的是undefined
,而在最底层的子组件拿$children
是个空数组。也要注意获得$parent
和$children
的值不同,$children
的值是数组,而$parent
是个对象bash
/**
* @desc 寻找指定组件实例
* @params {String} type 向上查找仍是向下查找
* @params {Object} context 当前上下文(通常指this,把this 传进来就能够了)
* @params {String} componentName 要寻找的指定的组件名
*/
function findComponents (type, context, componentName) {
if (['$parent', '$children'].indexOf(type) < 0) return
let currentComponent = context[type]
if (type === '$parent') currentComponent = [currentComponent]
let designatedCom = null
if (currentComponent.length) {
for(const com of currentComponent) {
const name = com.$options.name
if (name === componentName) {
designatedCom = com
break
} else {
designatedCom = findComponents(type, com, componentName)
if (designatedCom) break
}
}
return designatedCom
}
复制代码
这个方法能够向上向下寻找跨组件的子,父组件的实例,拿到实例后就能够拿到相应的data
和方法。app
使用此方法须要注意几点
1、第一个参数必须是['$parent', '$children']
中的一种,不然返回undefined
2、该方法必须在mounted
生命周期中使用,否则代码中的currentComponent.length
的值是0,(别问我为何,我也不知道为何)iview
而后就能够经过此方法获得你指定的组件实例,固然你可能会问,有Vuex
等其余的通讯方法,为何要使用这个方法,或者说在什么状况下合适使用该方法。若是你本身写了一个自定义通用组件,如今你的组员想用这个组件,可是你把控制组件状态的值都写在了Vuex
上了,这时候就麻烦了。这时候使用这个方法应该说比较好,不须要其余的外部依赖,即拿即用。 最后说一句,该方法出自iview
源码中的寻找组件方法,我只是将其稍微改造了下,你能够点此连接查看iview
源码。ui