Vue 使用篇(四):data数据的变化

一、背景

Vue中的数据模型仅仅是普通的JavaScript对象,然而当你在修改它们的时候,视图会自动进行更新。

当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
用户是看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

每个组件里都有一个watcher 实例对象,它会在组件渲染时把属性依赖记录下来,当setter被调用时会通知 watcher 重新计算重新渲染页面。

二、检测对象数据的变化

由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
因此Vue 不能检测到对象属性的添加或删除。

Vue 不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property)。
然而它可以使用 Vue.set(object, key, value)或者this.$set 实例方法将响应属性添加到嵌套的对象上。
而如果需要向一个已有对象添加多个属性,例如使用 Object.assign()创建一个新对象包含原对象属性和新的属性。

<div id="app">
  <div>{{object}}</div>
  <button @click='changeName'>修改对象原用属性</button>
  <button @click='addAge'>额外添加对象属性(新增属性是非响应式的)</button>
  <button @click='addSetColor'>额外添加对象属性(新增属性是响应式的)</button>
  <button @click='addSome'>额外添加多个对象属性(新增属性是响应式的)</button>
</div>

let vm = new Vue({
  el: "#app",
  data: {
    object:{
        name:'zhaojie'
    }
  },
  methods: {
    changeName () {
        this.object.name = 'madman' // 数据响应
    },
    addAge () {
        this.object.age = 18 // 数据无响应
    },
    addSetColor () { // 数据响应
        this.$set(this.object,'color','yellow')
        //Vue.set(vm.object,'color','yellow')
    },
    addSome () { // 数据响应
        this.object =  Object.assign({}, this.object, { a: 1, b: 2 })
    },
  }
})
复制代码

三、检测数组数据的变化

3.1 Vue数组变异方法

Vue官方规定了 7 个数组方法,这 7 个数组方法是在保持原用功能不变的前提下添加了响应式功能,使得可以触发数组的响应式,这 7 个数组方法分别是:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

3.2 解决Vue中无法检测的数组变动

Vue 对 data 方法返回的对象中的元素进行响应式处理时,如果元素是数组时,仅仅对数组本身进行响应式化,而不对数组内部元素进行响应式化。因此

1、当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
2、当你修改数组的长度时,例如:vm.items.length = newLength
Vue是无法检测数组的变动。

1、解决第一个问题使用以下方法可以实现与vm.items[indexOfItem] = newValue相同的效果。

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
或者
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
复制代码

2、解决第二个问题使用以下方法可以实现与vm.items.length = newLength相同的效果。

vm.items.splice(newLength)
复制代码

3.3 示例代码

<div id="app">
  <div>{{array}}</div>
  <button @click='changeArray'>通过索引修改数组值以及修改数组长度</button>
  <button @click='useMethod(4)'>使用变异方法修改数组</button>
  <button @click='changeValue(0,9)'>修改数组值并且数组能够响应的方法</button>
  <button @click='changeLength(1)'>修改数组长度并且数组能够响应的方法</button>
</div>

let vm = new Vue({
  el: "#app",
  data: {
    array : [1,2,3]
  },
  methods: {
    changeArray () { // 数据无响应
      this.array[0] = 0
      this.array.length = 1
    },
    useMethod (value) { // 数据响应
      this.array.push(value)
    },
    changeValue (index,value) { // 数据响应
      //this.$set(this.array,index,value)
      this.array.splice(index, 1, value)
    },
    changeLength (newLength) { // 数据响应
      this.array.splice(newLength)
    }
  }
})
复制代码

四、参考资料

转载于:https://juejin.im/post/5c95f55bf265da6113604009

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值