Vue - 使用 ref 访问嵌套的孩子

Posted

技术标签:

【中文标题】Vue - 使用 ref 访问嵌套的孩子【英文标题】:Vue - access nested childs using ref 【发布时间】:2018-09-15 12:42:23 【问题描述】:

我有自己内部使用的 vue 组件 - 数据可以有带有子元素的数组,我使用这个数组根据嵌套级别在循环中渲染它们,以及下一级、下一级等。

现在我想从父级运行子方法,然后 - 如果语句正常,也将其调用给子级,下一级等。

我用

    <mycomponent
            ref="myFirstLevelRefName"
            (...)
    ></mycomponent>

然后:

this.$refs.myFirstLevelRefName 

调用一级子级。但是子节点呢?我以这种方式在视图中使用它们:

    <mycomponent
            v-for="(subElement, index) in getSubelements()"
            ref="???"
            v-bind:data="subElement"
            v-bind:key="index"
    ></mycomponent>

我尝试将 this.$refs 从子级别发送到控制台,但它是空的。

我应该如何在嵌套元素中设置引用名称,然后从父级调用它们?

【问题讨论】:

【参考方案1】:

虽然在技术上可以访问嵌套子级的$refs...

Vue.component('mycomponent', 
    template: "#mycomponent",
);

new Vue(
  el: '#app',
  mounted() 
    console.log(
      'Second level <input>\'s value:',
      this.$refs.myFirstLevelRefName.$refs.mySecondLevelRefName.value
    )
  
)
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>

<template id="mycomponent">
    <div>
        <input ref="mySecondLevelRefName" value="Hello">
    </div>
</template>

<div id="app">
  <mycomponent ref="myFirstLevelRefName"></mycomponent>
</div>

对于简单的场景,执行父级/深层子级或深层祖先/兄弟级通信的一种方式是使用事件中心。 (复杂场景见Vuex。)

您将创建一个全局变量:

var eventHub = new Vue(); // use a Vue instance as event hub

要发出您将在任何组件中使用的事件:

eventHub.$emit('myevent', 'some value');

然后,您将在任何其他组件中收听该事件。该事件的动作可以是任何东西,包括方法调用(这是你想要的):

eventHub.$on('myevent', (e) => 
    console.log('myevent received', e)
    // this.callSomeMethod();
);

演示:

var eventHub = new Vue(); // use a Vue instance as event hub

Vue.component('component-first', 
    template: "#component-1st",
    methods: 
      myMethod() 
        eventHub.$emit('myevent', 'some value');
      
    
);
Vue.component('component-second', template: "#component-2nd");
Vue.component('component-third', 
  template: "#component-3rd",
  created() 
    eventHub.$on('myevent', (e) => 
      this.check();
    );
  ,
  methods: 
    check() 
      console.log('check method called at 3rd level child');
    
  
)

new Vue(
  el: '#app',
  data: 
    message: 'Hello Vue.js!'
  
)
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>

<template id="component-1st">
    <div>
        1st level component
        <button @click="myMethod">Trigger event at 1st level component that will call 3rd level child's method</button>
        <hr>
        <component-second></component-second>
    </div>
</template>
<template id="component-2nd">
    <div>
        <component-third></component-third>
    </div>
</template>
<template id="component-3rd">
    <div><h1>3rd level child</h1></div>
</template>

<div id="app">
  <component-first></component-first>
</div>

注意:如果在您的环境中创建一个专用实例作为事件中心很复杂,您可以将 eventHub 替换为 this.$root(在您的组件中)并使用您自己的 Vue 实例作为中心.

【讨论】:

我知道这是一篇相对较旧的帖子,但只是遇到了一个问题,即在组件重新渲染时多次创建事件。只需在组件的 beforeDestroy 钩子中添加eventHub.$off('myevent')this.$root.$off('myevent') @HamendraSunthwal 你能发布一个新问题并更好地说明你的问题吗?

以上是关于Vue - 使用 ref 访问嵌套的孩子的主要内容,如果未能解决你的问题,请参考以下文章

从与当前组件不同级别的其他组件访问 $refs

按组件名称的Vue.js $ children

vue父子组件兄弟组件之间的通信和访问

Vue.js $children 按组件名称

Vue 3 之:弄清 ref reactive toRef toRefs

vue-resource,自定义指令,注册组件,ref属性访问