剑走偏锋之Vue 组件通讯(一)—经过$parent和$children构建本身的通信方式

在我日常的开发中,不少问题都是见招拆招,遇到了便去解决。久而久之,出现了一个大问题,就是会反复的碰到这个问题,而反复去解决,由于上次解决的方式不必定能记到。就像你看你几个月前的代码,都以为:卧槽,谁的代码,这么烂。因此,最好的方式就是总结,不断总结。vue

Vue 的简便之处便在于组件,组件之间的复用让Vue项目维护起来十分简便。而其中组件之间的通讯就是重中之重,无论哪个项目都有组件之间的通讯。而针对不一样状况下的组件之间通讯又各不相同,简直五花八门。像最基础的props@emit 父子组件通讯,大型项目官方推荐的Vuex全局状态管理,小型项目试用的Bus通讯等等,接下来我就总结出几种剑走偏锋的几种组件通讯。api

vue 官方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

相关文章
相关标签/搜索