Доступ к $ refs при интерполяции не работает / вызывает ошибку (компоненты Vue.js 2.x) - PullRequest
0 голосов
/ 25 февраля 2019

Я сделал следующее codepen :

const sidebar = {
  name: "sidebar",
  template: "<p>SIDEBAR</p>",
  data() {
    return {
      active: true
    };
  },
  methods: {
    test() {
      alert("test: " + this.active)
    }
  }
};
new Vue({
  el: '#app',
  name: 'vue-instance',
  
  data() {
    return {
      title: "Title of the page"
    };
  }, 
  components: {
    sidebar: sidebar,  
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
    {{ title }}
  
    <sidebar ref="sidebar1">
    </sidebar>
  
  <button type="button" v-on:click="$refs.sidebar1.test()">Test sidebar</button>
   
<!-- {{ $refs.sidebar1.active }} this causes error! -->
  {{ $refs }}
</div>

Закомментированная строка вызывает ошибку: "message": "$refs.sidebar1 is undefined",

Таким образом, кажется, что в родительском компоненте во время рендеринга $refs коллекция пуста, но позже, при нажатии на кнопку, $refs работает нормально и может правильно обращаться к компоненту sidebar1.

Почему это так?Как можно получить интерполяцию {{ $refs.sidebar1.active }}, работающую в шаблоне родительского компонента?

Заранее спасибо!

1 Ответ

0 голосов
/ 25 февраля 2019

Почему это так?Как можно получить интерполяцию $refs.sidebar1.active, работающую в шаблоне родительского компонента?

Vue может заполнять ссылки только тогда, когда дочерние компоненты созданы в родительской функции render, а поле refs - нет.реактивный на всех.

Когда вы указываете обработчик щелчка, он включается в функцию и выполняется только при нажатии кнопки (как и ожидалось), к этому времени refs уже установлено (так как начальный процесс рендеринга завершен) и естьбез ошибок.

Vue docs: Доступ к экземплярам дочерних компонентов

В качестве решения для вашего примера: вы можете использовать реквизиты для управления дочерними элементами извне и модификатор sync дляразрешить ребенку менять опору как v-model.Также будет удобнее извлекать работу с refs в некоторую родительскую функцию:

const sidebar = {
  name: "sidebar",
  template: "<p>SIDEBAR</p>",
  props: ['active'],
  methods: {
    test() {
      alert("test: " + this.active)
    }
  }
};
new Vue({
  el: '#app',
  name: 'vue-instance',
  
  data() {
    return {
      active: false,
      title: "Title of the page"
    };
  }, 
  methods: {
    testChild() {
      this.$refs.sidebar1.test();
    }
  },
  components: {
    sidebar: sidebar,  
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
    {{ title }}
  
    <sidebar ref="sidebar1" :active.sync="active">
    </sidebar>
  
  <button type="button" v-on:click="active = !active">Toggle</button>
  <button type="button" v-on:click="testChild">Test child</button>
   
<!--      {{ $refs.sidebar1.active }} this causes error! -->
  {{ active }}
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...