简体   繁体   English

绑定到对象的 Vue.js 类在对象更新时没有改变

[英]Vue.js class binded to object is not changing on object update

I have a number of buttons, being generated wuth v-for directive.我有许多按钮,正在生成 wuth v-for 指令。 all of them have initial class, based on the string from an object.它们都有初始类,基于来自对象的字符串。 I have an event, that is changing this string on button click.我有一个事件,即在单击按钮时更改此字符串。 But the class is not being updated.但是课程没有更新。 What am i doing wrong?我究竟做错了什么?

<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>

I expect the button class to be updated upon respected object update.我希望按钮类在受尊重的对象更新时更新。 The object .color prperty is updated but the class remains initial.对象 .color 属性已更新,但类保持初始状态。

Due to the limitations of modern JavaScript (and the abandonment of Object.observe), Vue cannot detect property addition or deletion.由于现代 JavaScript 的限制(以及 Object.observe 的废弃),Vue 无法检测到属性的添加或删除。 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.由于 Vue 在实例初始化期间执行 getter/setter 转换过程,因此数据对象中必须存在一个属性,以便 Vue 对其进行转换并使其具有反应性。

Read more here: Reactivity in Depth .在此处阅读更多内容:深度反应性

Vue provides an API to add properties to nested level objects and to make them reactive. Vue 提供了一个 API 来向嵌套级别对象添加属性并使它们具有反应性。

To do so, you can use为此,您可以使用

Vue.set(object, propertyName, value);

You can also use the vm.$set method您也可以使用vm.$set方法

this.$set(this.someObject, 'b', 2);

So in your code, where you are setting the value of array you need to do所以在你的代码中,你在哪里设置你需要做的数组的值

this.$set(this.cells, i, {
                           id: i,
                           color: 'info'
                         });

See the complete snippet below:请参阅下面的完整片段:

 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>

Read in detail about data and methods in the Vue documentation .阅读Vue 文档中有关数据和方法的详细信息。

It should be noted that properties in data are only reactive if they existed when the instance was created.应该注意的是,数据中的属性只有在创建实例时存在时才具有反应性。 That means if you add a new property,like:这意味着如果您添加一个新属性,例如:

 vm.b = 'hi'

Then changes to b will not trigger any view updates.然后对 b 的更改将不会触发任何视图更新。

you can use Vue.set() or this.$set() api when you set the prop value in loop.在循环中设置 prop 值时,可以使用Vue.set()this.$set() api。

or replace the whole object like:或替换整个对象,如:

var cells = {}
for (var i = 0; i < 100; i++) {
    cells[i] = {
    id: i,
    color: 'info'
    }
}
this.cells = cells

and then, in click callback:然后,在点击回调中:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM