Vue array two-way binding problem (array update detection, object addition and removal properties)

Example: three lists were rendered 100,200,300 number first, click on the back button corresponding to digital by ten, this time using this.arr[index]=this.arr[index]*10;How the changes do not work, change the data in the array arr, but fails to render correctly Page.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <div v-for="(item,index) in arr">
            {
    
    {
    
    item}}
            <button @click='aaa(item,index)'>点击数字改变</button>
        </div>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    var app = new Vue({
    
    
        el: '#app',
        data: {
    
    
            arr:[
                100,
                200,
                300
            ]
        },
        methods: {
    
    
            aaa(item,index) {
    
    
                console.log('进入aaa里面了')
                console.log(item)
                console.log(index)
                this.arr[index]=this.arr[index]*10;//不能使用
                console.log(this.arr)
            }
            
        }
    })
</script>

</html>


Insert picture description here
Solution one:

//参数一:要更改的原数组,参数二:索引,参数三:更改的值
         aaa(item,index) {
    
    
               Vue.set(this.arr,index,item*10);
        }

Solution 2: app.$set is just an alias of Vue.set.

         aaa(item,index) {
    
    
                 this.$set(this.arr, index, item * 10);
                 //app.$set(app.arr, index,item * 10);
        }

Solution three: use the array method

         aaa(item,index) {
    
    
             this.arr.splice(index,1,item*10)
        }

Important:
Vue wraps the change methods (7) of the listened array, so they will also trigger the view update . When processing arrays, you can choose these methods to achieve responsiveness. These wrapped methods include:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
push() 向数组的后面添加元素,返回值:数组的新长度  arr.push(4,5)
pop()  从数组的尾部删除一个元素,返回删除的元素  arr.pop() 不用传参
unshift() 向数组的前面添加元素,返回值:数组的新长度  arr.unshift(0,1)
shift() 从数组头部删除一个元素,返回删除的元素  arr.shift() 不用传参
splice() :
	删除:两个参数,splice(index,num) 删除的第一项的位置以及要删除的项数
	添加:三个参数,插入起始位置、删除的项数(为0)、插入的项,向指定位置插入任意数量的项。arr.splice(1,0,"or","ue")
	替换:先删除再添加,三个参数:起始位置、删除的项数、要添加的项数。添加的与删除的数量不一定要一致。arr.splice(1,2,"or","ue")
sort():对数组元素进行排序,默认根据字符串Unicode码进行排序,对数字进行排序时参数要传递一个比较函数。
	sortNumber(a,b){
    
    
	      return a-b
	}reverse():该方法用于颠倒数组中元素的顺序

The above methods will change the original array on which these methods are called. In contrast, there are also non-modifying methods, such as filter(), concat(), and slice(). They do not change the original array, but always return a new array. When using the non-change method, you can replace the old array with the new array:

example1.items = example1.items.filter(function (item) {
    
    
  return item.message.match(/Foo/)
})

Replacing the old array with a new array will not cause Vue to discard the existing DOM and re-render the entire list. Vue has implemented some smart heuristics in order to maximize the reuse of DOM elements, so use an array with the same elements to go Replacing the original array is a very efficient operation .

Knowledge points: (official document)

Due to JavaScript limitations, Vue cannot detect changes in arrays and objects. But we have to take some measures to circumvent these restrictions and ensure their responsiveness.

For arrays:

Vue cannot detect changes in the following arrays:

  • When you use the index to directly set an array item, for example: vm.items[indexOfItem] = newValue
  • When you modify the length of the array, for example: vm.items.length = newLength
var vm = new Vue({
    
    
  data: {
    
    
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的

Solve the problem of using indexes to set array items:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
//使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:
vm.$set(vm.items, indexOfItem, newValue)

Solve to modify the length:

vm.items.splice(newLength)





For the object:

Vue cannot detect the addition or removal of properties. Since Vue will perform getter/setter conversion on the property when initializing the instance, the property must exist on the data object in order for Vue to convert it into a reactive type. E.g:

var vm = new Vue({
    
    
  data:{
    
    
    a:1
  }
})
// `vm.a` 是响应式的
vm.b = 2
// `vm.b` 是非响应式的

Object property addition:
Use the Vue.set(object, propertyName, value) method to add responsive properties to nested objects.

Vue.set(vm.someObject, 'b', 2)

Use the vm.$set instance method, which is also an alias for the global Vue.set method:

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

An existing object is assigned multiple new properties. In this case, a new object should be created with the original object and the property of the object to be mixed.

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({
    
    }, this.someObject, {
    
     a: 1, b: 2 })

Object property removal:
Use this. delete to delete a property in the object: Syntax: this. delete to delete a property in the object: Syntax: this.D E L E T E to delete the addition of the object in the certain one genera of : Language Method : T H I S . Delete (this.obj, 'Key')

this.$delete(this.someObject,'a')

Guess you like

Origin blog.csdn.net/qq_43812504/article/details/114626059