在我平常的开发中,很多问题都是见招拆招,遇到了便去解决。长此以往,出现了一个大问题,就是会反复的碰到这个问题,而反复去解决,因为上次解决的方式不一定能记到。就像你看你几个月前的代码,都觉得:卧槽,谁的代码,这么烂。所以,最好的方式就是总结,不断总结。
这张图片就是
Vue
的简便之处便在于组件,组件之间的复用让Vue
项目维护起来十分简便。而其中组件之间的通信就是重中之重,不管哪一个项目都有组件之间的通信。而针对不同情况下的组件之间通信又各不相同,简直五花八门。像最基础的props
和@emit
父子组件通信,大型项目官方推荐的Vuex
全局状态管理,小型项目试用的Bus
通信等等,接下来我就总结出几种剑走偏锋的几种组件通信。
Vue
官方
api 中的,通过
$parent
和
$children
就可以访问组件的实例,拿到实例代表什么?代表可以访问此组件的一切方法和
data
。虽然官方说节制的使用,但是我还是选择了无视。接下来就该思考下怎么去拿到指定组件的实例。
这应该是个通用的方法,原理就是通过不断遍历找到符合标准的组件实例,通过拿到的组件实例来拿到该实例的方法和data
要注意边界情况,如在
#app
上拿$parent
得到的是new Vue()
的实例,在这实例上再拿$parent
得到的是undefined
,而在最底层的子组件拿$children
是个空数组。也要注意得到$parent
和$children
的值不一样,$children
的值是数组,而$parent
是个对象
/**
* @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
和方法。
使用此方法需要注意几点
一、第一个参数必须是['$parent', '$children']
中的一种,否则返回undefined
二、该方法必须在mounted
生命周期中使用,不然代码中的currentComponent.length
的值是0,(别问我为什么,我也不知道为什么)
然后就可以通过此方法得到你指定的组件实例,当然你可能会问,有Vuex
等其他的通信方法,为什么要使用这个方法,或者说在什么情况下合适使用该方法。如果你自己写了一个自定义通用组件,现在你的组员想用这个组件,但是你把控制组件状态的值都写在了Vuex
上了,这时候就麻烦了。这时候使用这个方法应该说比较好,不需要其他的外部依赖,即拿即用。 最后说一句,该方法出自iview
源码中的寻找组件方法,我只是将其稍微改造了下,你可以点此链接查看iview
源码。