Vue - access nested childs using ref

白昼怎懂夜的黑 提交于 2019-11-30 20:35:12

While it is technically possible to access $refs of nested children...

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>

A way of performing parent/deep child, or deep ancestor/sibling communication, for simple scenarios, is using an event hub. (For complex scenarios, see Vuex.)

You would create a global variable:

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

To emit events you would use in any component:

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

You would, then, in any other component, to listen to that event. The action of that event could be anything, including a method call (which is what you want):

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

Demo:

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>

Note: If creating a dedicated instance as event hub is something complicated in your environment, you can replace eventHub with this.$root (inside your components) and use your own Vue instance as hub.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!