问题
我的页面结构是这样的。
根据组件循环布局组件,布局组件循环自身,直到遇到渲染组件为止。
我需要拿到最终所有的渲染组件的ref而触发其动作。但在实际过程中却遇到因为递归层次太深。拿不到所有的ref。而且因为布局组件比如标签页布局的特殊性只能拿到当前所在的标签页,而不能触发其他标签页的方法。
我当时用的方式是这样
// 地图渲染事件
if (Array.isArray(this.$refs.nestedComponents)) {
this.$refs.nestedComponents.forEach(item => {
item.drawMapRoutes(formData, params)
})
} else {
this.$refs.nestedComponents.drawMapRoutes(formData, params)
}
$refs这种方式不能获取到所有的渲染组件。最终换成了provide和inject的方式将所有组件注册到根组件。网上介绍的代码经过我的测试是无效的,折腾了点时间,特此记录
安装插件
// npm安装
npm install vue-ref --save
// main.js中
import ref from "vue-ref"
Vue.use(ref, { name: "ant-ref" }) // name是自定义api名称
在子组件上添加,我的是渲染组件
v-ant-ref="(dom) => setChildrenRef('nestedComponents', dom)"
解决方案
根组件
下面方法一定要放到根组件上,以便子组件全局注册
data() {
return {
nestedComponents: [],
}
}
provide() {
return {
nestedComponents: this.nestedComponents,
// 主动通知 将组件实例绑定在根组件上
setChildrenRef: (name, ref) => {
if (ref) {
// 渲染完毕后再追加,否则v-for不断的push,
// 数组不断改变,页面会不断渲染造成会有额外数据,
// 而且页面会warn报错
this.$nextTick(() => {
this.nestedComponents.push(ref)
})
}
},
// 主动获取 获取绑定的组件
getChildrenRef(name) {
return this.nestedComponents
},
// 获取根组件
getRef: () => {
return this
}
}
}
子组件
inject: {
nestedComponentsed: {
from: 'nestedComponents',
default: []
},
setChildrenRef: {
default: () => {}
},
getParentRef: {
from: 'getRef',
default: () => {}
},
getParentChildrenRef: {
from: 'getChildrenRef',
default: () => {}
}
}
获取所有渲染组件
this.nestedComponentsed.forEach(item => {
item.drawMapRoutes(formData, params)
})