[Vuejs]-How to re-render an HTML element after a value deep in an multi-dimension array changes?

0👍

Vue only observes the object’s own properties – that is, only 1 level deep, no more. So you can try one of these:

  • use this.$forceUpdate(); (https://v2.vuejs.org/v2/api/#vm-forceUpdate)
  • use this.$set(this.students[index], 'tags', this.students[index].tags.concat([value])); – once set, the tags array will be observed by Vue so you can use tags.push() on subsequent additions
  • use a hash-map for students’ tags
computed:
{
  studentTags()
  {
    const result = {};
    this.students.forEach(student =>
    {
      result[student.id] = student.tags;
    });
    return result;
  }
},
methods:
{
  addTag(studentId, tag)
  {
    this.studentTags[studentId].push(tag);
  }
}

0👍

We do not need to use Vue.set to push the new data in an array or sub-array. It will auto-handle by the vuejs.
However, we should use Set to reflect the updates in a sub-array.

See this example-

<template>
  <div id="app">
    <div v-for="(student, index) in students" :key="index">
     <button @click="addMoreTag(student.id)" style="background: green">
      Add more
     </button>
     <button
      v-for="(tag, tindex) in student.tags"
      :key="tindex + 't'"
      @click="updateTag(student.id, tag)"
     >
      {{ tag }}
     </button>
   </div>
  </div>
</template>

<script>
 export default {
   name: "App",

   data() {
     return {
      students: [
      {
       id: 1,
       name: "John",
       tags: ["one", "two"],
      },
      {
       id: 2,
       name: "Mira",
       tags: ["three", "five"],
      },
     ],
   };
  },

  methods: {
   addMoreTag(id) {
    let index = this.students.findIndex((item) => item.id === id);
    this.students[index].tags.push("new");
   },

   updateTag(student_id, tag) {
    let index = this.students.findIndex((item) => item.id === student_id);
    let tagIndex = this.students[index].tags.findIndex(
      (item) => item === tag
    );
    this.$set(this.students[index].tags, tagIndex, "updated");
   },
 },
};

I wrote in coodepen too- https://codesandbox.io/s/blissful-cdn-5kyt1c?file=/src/App.vue

Leave a comment