Vue - access nested childs using ref

前端 未结 1 1230
忘掉有多难
忘掉有多难 2020-12-30 03:38

I have vue component which I use inside himself - data can have array with subelements and I use this array to render them in loop, and next level, next level etc. according

相关标签:
1条回答
  • 2020-12-30 03:52

    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.

    0 讨论(0)
提交回复
热议问题