如何在v-for呈现的对象中发生更改时更新DOM?

wra*_*him 5 vue.js vue-component vuejs2 v-for

v-for用来渲染基于对象数组的列表.

<ul>
  <li v-for="category, i in categories"
  :class="{active: category.active}"
  @click="changeCategory(i)">
    <a>{{ category.service_type_name }}</a>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

单击列表项changeCategory(index)运行时:

changeCategory(index) {
    this.categories.forEach((c, i) => {
        c.active = (i != index)? false : true
    })
}
Run Code Online (Sandbox Code Playgroud)

因此,单击的列表项active属性将设置为true,所有其他属性设置为false,并且列表项将.active添加一个类(由于:class="{active: category.active}"模板中的行.

但是,DOM未更新以显示此更改.

无论如何在发生此更改时自动更新DOM,而不this.$forceUpdate()changeCategory(index)函数中使用?

编辑:更改mapforEach,DOM仍然不更新.

编辑:我正在使用带有打字稿的vue-class-components

import Vue from 'app/vueExt'
import { Component } from 'vue-property-decorator'
import * as Template from './services.vue'

@Component({
    mixins: [Template]
})
export default class Services extends Vue {
    categories = []

    created() {
        this.api.getServiceSetupCatagories().then((res) => {
            this.categories = res.categories
            this.categories.forEach((c, i) => {
                // adding active property to the object
                // active = true if i = 0, false otherwise
                c.active = (i)? false : true
            })
        })
    }

    changeCategory(index) {
        this.categories.forEach((c, i) => {
            c.active = (i != index)? false : true
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

Ber*_*ert 2

讨论该问题后,我建议采用以下替代方法。

添加模板并将其更改为以下内容activeIndexdata

<ul>
  <li v-for="category, i in categories"
      :class="{active: activeIndex === i}"
      @click="activeIndex = i">
    <a>{{ category.service_type_name }}</a>
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

这似乎适用于@wrahim。

我相信原始代码的根本问题是该active属性被添加到 Vue 的变更检测警告category之一中。