Я использую Vue.js 2.5.17
У меня есть два компонента: App (родительский) и TreeNode (дочерний), которые отображают древовидную структуру элементов глубоко вложенного объекта.Каждый узел в дереве представлен компонентом TreeNode, который является рекурсивным компонентом.
компонент TreeNode
const TreeNode = Vue.component('TreeNode', {
name: 'TreeNode',
template: '#treenode',
props: {
model: Object,
},
data() {
return {
open: false,
};
},
computed: {
isExpandable() {
return this.model.children &&
this.model.children.length;
},
},
methods: {
toggle() {
if (this.isExpandable) {
this.open = !this.open;
}
},
},
});
шаблон TreeNode
<script type="text/x-template" id="treenode">
<li>
<input type="checkbox" :id="model.name" style="display:none;"/>
<label :for="model.name" style="color:gray;" @click="toggle">
{{ model.name }}
{{ model.data.example }}
</label>
<ul v-show="open" v-if="isExpandable">
<TreeNode
class="item"
v-for="(model, index) in model.children"
:key="index"
:model="model">
</TreeNode>
</ul>
</li>
</script>
шаблон компонента приложения
<script type="text/x-template" id="oulist">
<div>
<div id="unitsTable" class="row filterlist treelist b_widget2" style="width:85%;">
<div class="css-treeview">
<TreeNode
class="item"
:model="items">
</TreeNode>
</div>
</div>
</script>
Компонент приложения
const App = Vue.component('App', {
template: '#oulist',
components: {
TreeNode,
},
data() {
return {
items: {
name: 'item1',
data: { example: '1' },
children: [
{
name: 'item11',
children: [],
data: { example: '1' },
},
{
name: 'item12',
children: [
{ name: 'item121', children: [], data: { example: '1' } },
{ name: 'item122', children: [], data: { example: '1' } },
],
data: { example: '1' },
},
],
},
};
},
methods: {
updateItem(currNode, name, data) {
if (currNode.name === name) {
Object.assign(currNode.data, data);
this.items = Object.assign({}, this.items); // tried to create a new object here and overwrite it, but it didn't help
return;
}
if (currNode.children) {
currNode.children.forEach(c => this.updateItem(c, name, data));
}
},
},
});
Приведенный выше объект является лишь примером, у моего реального объекта гораздо больше вложенных уровней и элементов на уровень.
Проблема в том,Я сталкиваюсь с тем, что всякий раз, когда свойство глубоко в моем объекте элементов изменяется (точнее, примерное свойство объекта данных внутри узла), DOM не обновляется.Я прочитал предупреждения о реактивности и увидел, что добавление новых свойств не является реактивным по умолчанию, но я не добавляю новые свойства здесь, просто изменяю существующие.
Когда данные из узла дерева обновляются, я пересекаюобъект, чтобы найти правильный узел и обновить его свойства следующим образом:
updateItem(currNode, name, data) {
if (currNode.name === name) {
Object.assign(currNode.data, data);
this.items = Object.assign({}, this.items); // tried to create a new object here and overwrite it, but it didn't help
return;
}
if (currNode.children) {
currNode.children.forEach(c => this.updateItem(c, name, data));
}
},
this.updateItem(this.items, 'item121', { example: 'newVal' });
Любые советы?Спасибо!
РЕДАКТИРОВАТЬ: данные всегда изменяются только в родительском (App) компонент.