Solution to the problem that Vue binding objects and array variables cannot be rendered after changing

Solution to the problem that Vue binding objects and array variables cannot be rendered after changing

Project scenario:

There is a <ul> tag on the page display. We need to display the list data dynamically. In addition to the list values, there are other values ​​to be displayed on our page. Therefore, the data structure of the list data is an array under an object. After dynamically modifying the data, it is found that it is not automatically rendered.

Problem description:

When you click the "click me!" button, the data changes and is output to the console, but the list data is not rendered.
The code is as follows:

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
  <button @click="pushDataToDataList">click me!</button>
  <ul>
    <li v-for="(item, i) in form.dataList" :key="item">
      {{ i + ":" + item }}
    </li>
  </ul>
</div>
<script>
  let app = new Vue({
    data: function() {
      return {
        form: {}
      }
    },
    methods: {
      pushDataToDataList() {
        if (this.form.dataList == null) {
          this.form.dataList = []
        }
        this.form.dataList.push("abc" + this.form.dataList.length)
        console.log(this.form.dataList)
      }
  }
  }).$mount('#app')
</script>

Chrome's console displays

Cause Analysis:

After consulting the official documentation, we found the following passage

Due to limitations of JavaScript, Vue cannot detect changes in arrays and objects. However there are ways to work around these limitations and still keep them responsive.

  1. For objects: Vue cannot detect the addition or removal of properties. Since Vue performs getter/setter conversion on the property when initializing the instance, the property must exist on data object in order for Vue to convert it to responsive.
  2. For arrays: Vue cannot detect changes to the following arrays:
  • When you set an array item directly using its index, for example: vm.items[indexOfItem] = newValue
  • When you modify the length of an array, for example: vm.items.length = newLength

The reason is clear here. Our data is not rendered because at the beginning, there is no dataList attribute in the form under data. Therefore, even if the value changes later, Vue cannot detect its change. And it's not just for arrays, it's the same even for js objects. In addition, directly modifying the elements of the array by pressing the subscript will not trigger view rendering .
The following array methods will trigger array rendering:

  • push(element) // Add an element to the end of the array
  • pop() // remove the last element of the array and return it
  • shift() // remove the first element of an array and return it
  • unshift(ele1, ele2, …, eleN) // Add one or more elements to the beginning of the array and return the new length
  • splice(start, deleteCount?, …item) // Delete an element in an array and replace it with a new element
  • sort() // Sort the array and modify the position of the array elements
  • reverse() // Reversing array elements will modify the position of array elements

Solution:

1. In the form object under data, set dataList property. Since the front end knows the structure of the code when processing the data, setting it up in advance also facilitates subsequent development and understanding.建議使用

data: function() {
  return {
    form: {
      dataList: null
    }
  }
}

2. Use this.$set() method

pushDataToDataList() {
  if (this.form.dataList == null) {
    // First set the dataList property under form this.$set(this.form, 'dataList', [])
  }
  this.form.dataList.push("abc" + this.form.dataList.length)
  console.log(this.form.dataList)
}

Reference Links

Notes on Vue's detection of data changes

This is the end of this article about how to solve the problem that Vue bound objects and array variables cannot be rendered after changes. For more related content about the problem that Vue bound objects and array variables cannot be rendered after changes, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of Vue's SSR server-side rendering example
  • Vue+elementUI component recursively implements foldable dynamic rendering multi-level sidebar navigation
  • A brief discussion on the whole process of Vue's first rendering
  • Detailed explanation of incompatible changes in rendering functions in Vue3
  • Implementing Markdown rendering in Vue single-page application

<<:  Quickly solve the problems of incorrect format, slow import and data loss when importing data from MySQL

>>:  How to install MySQL 8.0.13 in Alibaba Cloud CentOS 7

Recommend

Dockerfile implementation code when starting two processes in a docker container

I want to make a docker for cron scheduled tasks ...

uniapp realizes the recording upload function

Table of contents uni-app Introduction HTML part ...

Pitfall notes of vuex and pinia in vue3

Table of contents introduce Installation and Usag...

How to completely delete and uninstall MySQL in Windows 10

Preface This article introduces a tutorial on how...

Summary of the use of MySQL date and time functions

This article is based on MySQL 8.0 This article i...

Three properties of javascript objects

Table of contents 1. writable: writable 2. enumer...

Seven Principles of a Skilled Designer (2): Color Usage

<br />Previous article: Seven Principles of ...

Definition and function of zoom:1 attribute in CSS

Today I was asked what the zoom attribute in CSS ...