我想知道对我的情况有什么好办法。请考虑以下代码:
<div id="app-4">
<ol>
<li v-for="todo in todos">
{{ todo.text }} + {{todo.added_text}} <button v-on:click="add_text(todo)">do</button>
</li>
</ol>
</div>
<script type="text/javascript">
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue' },
]
},
methods: {
add_text(item){
index = this.todos.indexOf(item);
this.todos[index].added_text = "something else";
// this.todos[index].text = 'learn more';
}
}
})
</script>
如果按下按钮,我想添加todo.added_text。但是,因为当vue被实例化时,这个属性不是数组中元素的一部分,所以这个属性根本不出现(这是我的假设,我可能是错的)。
但是,当我在同一个元素中更改其他内容时(例如注释行:this.todos [index] .text ='了解更多';),然后todo.text和todo.added_text都会更新。
我的问题是,除了更改同一元素的其他属性外,告诉vue元素中有什么变化的好方法是什么?
答案 0 :(得分:1)
但是,因为当实例化vue时,此属性不是数组中元素的一部分,所以此属性根本不显示
是的,你是对的
当您将纯JavaScript对象作为其数据选项传递给Vue实例时,Vue将遍历其所有属性并使用Object.defineProperty将它们转换为getter / setter。
getter / setter对于用户是不可见的,但是当他们访问或修改属性时,它们使Vue能够执行依赖性跟踪和更改通知。
Vue无法检测属性添加或删除。由于Vue在实例初始化期间执行getter / setter转换过程,因此数据对象中必须存在一个属性,以便Vue转换它并使其具有反应性。
您使用Vue.set(object, key, value)
执行此操作例如
Vue.set(vm.someObject, 'b', 2)
阅读here
答案 1 :(得分:0)
您可以通过分配一个反应性元素来获得反应性。 this.todos[index]
已经处于反应状态,因此,如果您重新分配整个内容,则所有部件都将处于反应状态。因为它是一个数组元素,所以必须使用set
,但是您可以将其用于整个对象一次,而不是用于每个添加的成员:
add_text(item){
const index = this.todos.indexOf(item);
const newObject = Object.assign({}, item, {
text: 'learn more',
added_text: 'something else'
});
this.$set(this.todos, index, newObject);
}