I was wondering what a good approach is for my situation. Consider the following code:
<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>
I want to add the todo.added_text if the button is pressed. But, because this property was not part of the elements in the array when vue was instantiated, this property does not appear at all (this is my assumption, I could be wrong).
However, when I change something else in the same element (e.g. the commented line: this.todos[index].text = 'learn more';), then both todo.text and todo.added_text update.
My question is, what is a good approach to tell vue that something changed in the element, besides changing some other property of the same element?
Yes you're right
When you pass a plain JavaScript object to a Vue instance as its data option, Vue will walk through all of its properties and convert them to getter/setters using Object.defineProperty.
The getter/setters are invisible to the user, but under the hood they enable Vue to perform dependency-tracking and change-notification when properties are accessed or modified.
Vue cannot detect property addition or deletion. Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.
You do this with
Vue.set(object, key, value)
For exampleRead here
You can get reactivity by assigning to a reactive element.
this.todos[index]
is already reactive, so if you reassign the whole thing, all pieces will be reactive. Because it is an array element, you have to useset
, but you can use it once for the whole object rather than for each added member: