Я работаю над веб-приложением среднего размера на основе vue.js. Я столкнулся с несколькими проблемами виртуального DOM, в основном связанными с жизненным циклом экземпляров vue.
Следующий фрагмент кода (jsFiddle также доступен здесь) демонстрирует некоторые из этих проблем. Компонент vue test-component получает значение свойства и обновляет свое внутреннее состояние, используя это значение.
Каждый раз, когда набор данных изменяется (путем сортировки или новыми данными), свойства обновляются, а внутреннее состояние - нет. В этом довольно легко убедиться, запустив фрагмент кода и нажав кнопки.
Я понимаю, что атрибут компонента data - это функция, и похоже, что он вызывается только при создании компонента. Так объясняется, что происходит. Дело в том, что я не знаю, как добиться желаемого поведения, а именно: внутреннее состояние всех дочерних компонентов обновляется при изменении источника данных.
- Есть ли обратный вызов жизненного цикла, который срабатывает, когда компонент
"обновляется"? Мне нужен обратный вызов только для обновления компонента. Нужно ли мне индивидуально следить за изменениями опоры? Это было бы некрасиво. - Есть ли чистый способ обновить внутреннее состояние при изменении реквизита?
- Можно ли уничтожить все дочерние компоненты и заставить их воссоздать заново? Я знаю, что это не лучший вариант, но он решит все мои проблемы с привязкой данных :)
- Как vue решает, когда компонент будет выпущен или использован повторно? В моем примере компоненты исчезают, когда размер набора данных изменяется с 4 на 3, но внутреннее состояние первых трех элементов не изменяется, поэтому первые три элемента используются повторно.
Перемещение всего состояния в vuex было бы возможным решением, но некоторые компоненты являются общими, и я не хочу, чтобы они содержали информацию о деталях хранилища vuex. На самом деле я использую vuex для большинства компонентов, но для действительно общих компонентов я не думаю, что это хороший вариант.
var testComponent = Vue.component('test-component', {
template: '#component_template',
props: ['prop1'],
data: function(){
return {
internalState: this.prop1
}
}
})
new Vue({
el: "#app",
data: function(){
return {
items: [
'Item 1',
'Item 2',
'Item 3'
],
dataToggle: true,
sorted: true
};
},
methods: {
sortDataSet: function(){
if(this.sorted){
this.items.reverse();
} else {
this.items.sort;
}
}
,changeDataSet: function(){
if(this.dataToggle){
this.items = ['Item 4', 'Item 5', 'Item 6', 'Item 7'];
} else {
this.items = ['Item 1', 'Item 2', 'Item 3'];
}
this.dataToggle = !this.dataToggle;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.2/vue.js"></script>
<body>
<h3>
Components internal state is not being updated
</h3>
<div id="app">
<button v-on:click="changeDataSet">
Change data
</button>
<button v-on:click="sortDataSet">
Sort data
</button>
<ul>
<li v-for="item in items">
<test-component :prop1="item">
</test-component>
</li>
</ul>
</div>
</body>
<script id="component_template" type="x-template">
<div>Prop: {{prop1}} || Internal state: {{internalState}}</div>
</script>