<template>
  <div>
    <h2>devicebase 页面</h2>
    <button @click="addSlice">添加1 slice用法</button><br>
    <span v-for="item in list" :key="item.id">{{item}}</span>
    <br>
    <button @click="test">test</button>
    <br>
    <button @click="addSet">添加2 this.$set用法</button><br>
    <span v-for="item in listSet" :key="item.id">{{item}}</span>
  </div>
</template>

<script>
export default {
  data () {
    return {
      list: [{
        a: '1'
      }, {
        b: '2'
      }],
      listSet: [{
        a1: '1'
      }, {
        b1: '2'
      }]
    }
  },
  methods: {
    addSlice () {
      console.log('触发:add事件')
      console.log(this.list[0])
      console.log(this.list[1])
      // let group = []
      // let group = this.list
      let group = this.list.slice(0) // slice(0)的意思是把vue中data下list特殊格式(属于vue的数据格式)给转换为js正常的数据格式
      let obj = { c: '3' }
      group[2] = obj
      this.list[2] = obj // 数组不可以直接添加对象,必须新建一个数组   this is an error understand
      console.log(this.list[2])
      this.list = group
    },
    test () {
      console.log('触发:test事件')
      let list = [{
            a: '1'
          }, {
            b: '2'
          }]
      let obj = { c: '3' }
      list[2] = obj // list数组写在js中是可以直接list[i]添加对象的,data中list: 是不可以的,受vue中data的影响,可以this.$set,也可以this.list=group准确的说是data中的数据格式是vue专属的,和js中数组格式不一样.
      console.log(list)
    },
    addSet () {
      console.log('触发:addSet事件')
      let group = {}
      group.c1 = '3' 
      this.$set(this.listSet, this.listSet.length, group)
      this.$set(this.list, this.list.length, group)
    }
  }
}
</script>

 

 

Q:在vue中不能直接对data定义的list数组添加元素,解决方法有两种?

1.用Vue专门针对此bug设定的方法,this.$set 或者是 Vue.set(需当前页面impprt Vue from 'vue')

2.在script中先手动将list转化为js数组数据格式,this.list.clice(0),之后用js的方法即可

 

附注:slice(0)的深入理解

深拷贝和slice(0)有什么区别

Q:var array = listenerArray.slice(0); 和深拷贝有什么区别呢?还有Object.assign() 请做一个区分吧

深拷贝:拷贝地址和拷贝原对象的属性树,这样拷贝和原对象就是完全独立的了,所以更改'副本'不能更改原对象,这涉及到引用类型和基本类型的概念

浅拷贝:类似于引用类型,只拷贝地址,可以通过"副本"来修改原对象

 

.js的传参是按值传递。但是对于引用类型,传递的值是原对象在内存中的地址,所以拷贝仅仅是获取了原对象的引用,对拷贝进行修改,原对象也会被修改,要想避免这种情况出现,就不能仅仅拷贝地址,而是要将原对象的属性树遍历复制到拷贝上,这样拷贝和原对象就是完全独立的了,这就是要达到深拷贝的层次,之前就叫浅拷贝的层次

如果所有值都是非引用类型,那么深浅拷贝没有差别

slice可看作浅拷贝,因为如果listenerArray有引用类型的元素的话,slice仅仅是复制了元素的地址,而深拷贝是复制了整个元素

ar fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];

var citrus = fruits.slice(1,3);

修改citrus数组里的值,并不会改变fruits,这不就是深克隆吗?

对于元素全部为基础类型的数组,slice等价于深克隆。对于含有引用类型元素的数组则不然

Logo

前往低代码交流专区

更多推荐