ref

ref是vue预设的一个属性,通过$refs我们可以获取dom或者组件实例。

<p ref="p">获取到dom</p>

<child-component ref="child">获取到一个组件实例</child-component>

通过this.$refs.p我们获取到的是html元素p的dom

通过this.$refs.child获取的是组件child-component的实例。

但是this只能获取到当前组件上下文的实例或者dom,但是如果我们跨层级获取,那就有点麻烦了。ref只能获取当前组件上下文组件,无法跨层级。

递归方式

this.$parent 访问父实例

this.$children 当前实例的直接子组件。(数组,不保证顺序,不是响应式)

this.$parent.$parent.$refs.xxx 跨级访问父组件

this.$children[0].$children[1].$refs.xxx 跨级访问子组件

使用这种方式,代码繁琐,性能低效。

优雅的方式

我们需要使用到一个自定义指令,这个指令已经有人做成插件了,我们可以直接安装

yarn add vue-ref --dev

安装完毕后在main.js中引用

import ref from "vue-ref";
Vue.use(ref, { name: "ant-ref" });

name表示自定义指令名

引用完毕后我们还需要配合provide和inject。

我们需要在父组件中provide声明几个方法,然后在子组件中通过自定义指令的方式,自动将需要跨层级访问的组件实例通过provide声明的方法,统一挂载到父组件实例上。

获取的时候呢,也是通过provide的方法获取挂载到父组件上的子组件实例。

父组件

<script>
export default {
  provide() {
    return {
      //挂载到父组件的方法
      setChildrenRef: (name, ref) => {
        this[name] = ref;
      },
      //获取组件实例的方法
      getChildrenRef: (name) => {
        return this[name];
      },
      //获取父组件实例
      getRef: () => {
        return this;
      },
    };
  },
}
</script>

子组件

<template>
  <div class="border2">
    <h3 v-ant-ref="c => setChildrenRef('childrenE', c)">E 结点</h3>
  </div>
</template>
<script>
export default {
  inject: {
    setChildrenRef: {
      default: () => {}
    },
    getParentRef: {
      from: "getRef",
      default: () => {}
    },
    getParentChildrenRef: {
      from: "getChildrenRef",
      default: () => {}
    }
  }
};
</script>

这样一个跨层级获取组件实例就完成了。

补充

//获取根组件实例 
this.getParentRef()
//获取指定名称组件实例
this.getParentChildrenRef("childrenH")
//这里输出的是DOM
this.getParentChildrenRef("childrenE")
分类: vue 开发实战 标签: vueprovideinjectrefrefs跨层级组件实例vue-ref

评论

暂无评论数据

暂无评论数据

目录