我有许多按钮,是通过v-for指令生成的。它们都基于对象的字符串具有初始类。我有一个事件,那就是单击按钮时更改此字符串。但是该类没有被更新。我在做什么错了?
<template>
<v-layout>
<v-btn v-for="cell in cells" :key='cell.id' v-bind:class='cell.color'
v-on:click='click(cell.id)'>
<p v-if="cell.win">win</p>
<p>{{cell.id}}</p>
</v-btn>
</v-layout>
</template>
<script>
export default {
data: () => {
return {
cells: {
},
winId: 0,
}
},
methods: {
generateCells() {
this.winId = Math.floor(Math.random() * 100);
for (var i = 0; i < 100; i++) {
this.cells[i] = {
id: i,
color: 'info'
}
}
},
click(id) {
if (this.cells[id] == this.winId) {
alert('you win');
this.cells[id].color = 'success';
} else {
this.cells[id].color = 'warning';
}
}
},
created() {
this.generateCells();
}
}
</script>
我希望按钮类可以在对象更新后更新。对象.color prperty已更新,但该类保持初始状态。
答案 0 :(得分:1)
由于现代JavaScript的局限性(以及Object.observe的放弃),Vue无法检测到属性的添加或删除。由于Vue在实例初始化期间执行getter / setter转换过程,因此,数据对象中必须存在一个属性,以便Vue对其进行转换并使其具有反应性。
在此处了解更多信息:Reactivity in Depth。
Vue提供了一个API,可以向嵌套的关卡对象添加属性并使它们具有反应性。
为此,您可以使用
Vue.set(object, propertyName, value);
您还可以使用vm.$set
方法
this.$set(this.someObject, 'b', 2);
因此,在您的代码中,您需要在其中设置数组的值
this.$set(this.cells, i, {
id: i,
color: 'info'
});
请参阅下面的完整代码段:
window.onload = () => {
new Vue({
el: '#app',
data: () => {
return {
cells: {
},
winId: 0,
}
},
methods: {
generateCells() {
this.winId = Math.floor(Math.random() * 100);
for (var i = 0; i < 100; i++) {
this.$set(this.cells, i, {
id: i,
color: 'info'
})
}
},
click(id) {
if (this.cells[id] == this.winId) {
alert('you win');
this.cells[id].color = 'success';
} else {
this.cells[id].color = 'warning';
}
}
},
created() {
this.generateCells();
}
})
}
body {
padding: 1rem;
}
.info {
color: blue;
}
.warning {
color: red;
}
.success {
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<v-layout>
<v-btn v-for="cell in cells" :key='cell.id' v-bind:class='cell.color' v-on:click='click(cell.id)'>
<p v-if="cell.win">win</p>
<p>{{cell.id}}</p>
</v-btn>
</v-layout>
</div>
答案 1 :(得分:0)
详细了解Vue documentation中的数据和方法。
应该注意的是,数据中的属性只有在它们具有属性时才是反应性的 创建实例时存在。这意味着如果您添加新 属性,例如:
vm.b = 'hi'
对b的更改不会触发任何视图更新。
在循环中设置prop值时,可以使用Vue.set()
或this.$set()
API。
或替换整个对象,例如:
var cells = {}
for (var i = 0; i < 100; i++) {
cells[i] = {
id: i,
color: 'info'
}
}
this.cells = cells
然后在点击回调中:
var newCell = {}
if (this.cells[id] == this.winId) {
alert('you win');
newCell[id] = {id:id,color:'success'}
} else {
newCell[id] = {id:id,color:'warning'}
}
this.cells = Object.assign({},this.cells,newCell)