How to update the DOM when changes occur in an object created by v-for?

I use v-forto display a list based on an array of objects.

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

When you click on a list item, it changeCategory(index)is executed:

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

Thus, the attribute attribute clicked on activegets the value true, and all the others - false, and the list item gets the class added to it .active(because of the line :class="{active: category.active}"in the template.

However, the DOM is not updated to show this change.

Do I need to update the DOM at all automatically with this change without using this.$forceUpdate()the function changeCategory(index)?

edit: changed mapto forEach, the DOM is still not updating.

edit: I am using vue-class-components with typescript

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
        })
    }
}
+4
2

.

activeIndex data .

<ul>
  <li v-for="category, i in categories"
      :class="{active: activeIndex === i}"
      @click="activeIndex = i">
    <a>{{ category.service_type_name }}</a>
  </li>
</ul>

@wrahim.

, , active category, Vue .

+1

, . , . ( : , .)

new Vue({
  el: '#app',
  data: {
    categories: [{
        service_type_name: 'one',
        active: false
      },
      {
        service_type_name: 'two',
        active: false
      }
    ]
  },
  methods: {
    changeCategory(index) {
      this.categories.map((c, i) => {
        c.active = (i != index) ? false : true
      })
    }
  }
});
.active {
  background-color: lightgray;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.0/vue.min.js"></script>
<ul id="app">
  <li v-for="category, i in categories" :class="{active: category.active}" @click="changeCategory(i)">
    <a>{{ category.service_type_name }}</a>
  </li>
</ul>
Hide result
0

Source: https://habr.com/ru/post/1676069/


All Articles