问题
Until now, I was trying to change the value of an object property to false using @click='review.isActive = true'
, however, it turns out Vue cannot detect such changes which means that property won't be reactive.
Based on the documentation https://vuejs.org/v2/guide/list.html#Caveats, this can be avoided by using one of the following methods:
Vue.set(vm.reviews, index, true)
vm.reviews.splice(index, 1, true)
Sadly I get an error using either way. I assume I don't quite understand how the Vue instance works and I'm trying to access it when I shouldn't be able to.
I assume Vue/vm are supposed to be the Vue instance but I can't seem to access it.
In both cases, I get error "Property or method "vm"/"Vue" is not defined on the instance but referenced during render."
I'm using Vue webpack-simple webpack template and my Vue instance seems to be initialized in main.js file like this:
var vm = new Vue({
el: '#app',
router: router,
store: store,
render: h => h(App)
});
The file in which the array manipulation is happening is different and a component.
回答1:
Assuming your review
object is an item in your reviews
array and that they do not initially have an isActive
property but you'd like to add one, you can use vm.$set
to add a new reactive property.
For example
new Vue({
el: '#app',
data: {
reviews: [{
id: 1,
name: 'Review #1'
},{
id: 2,
name: 'Review #2'
},{
id: 3,
name: 'Review #3'
}]
}
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<div v-for="review in reviews" :key="review.id">
<p>
Review {{ review.name }} status:
<code>{{ review.isActive ? 'ACTIVE' : 'INACTIVE' }}</code>
</p>
<button @click="$set(review, 'isActive', true)">Activate</button>
</div>
</div>
Note the use of $set
in the @click
handler.
From the comment below, if you wanted to add new properties after the data is retrieved, do it before you assign the value to your data property, eg
this.reviews = data.from.somewhere.map(review => ({...review, isActive: false}))
If you must add the new property after the data is assigned, you need to use vm.$set
to make it reactive
this.reviews.forEach(review => {
this.$set(review, 'isActive', false)
})
Once these properties are added reactively, you can go back to simply changing them without $set
<button @click="review.isActive = true">
来源:https://stackoverflow.com/questions/55719656/trying-to-change-object-property-and-keep-reactivity-property-or-method-vm-is