说完了对象的监听和后期添加对象的操作,接下来,我们来说一说针对于数组的监听。

1、首先还是定义一组数据用于展示,hobbys 为字符串数组,friends 为对象数组

const vm = new Vue({
  el: '#root',
  data() {
    return {
      hobbys: ['抽烟', '喝酒', '烫头'],
      firends: [
        { name: 'al', age: 20 },
        { name: 'hj', age: 22 }
      ]
    }
  },
})

2、展示完了之后,我们在控制台上查看 vm.data 发现 两个数组中的值,并没有像对象中的值一样,绑定一个 get 和 set 方法

这也就是意味着,如果我通过 vm._data.hobbys 去修改 hobbys 的第一个值的时候,Vue内的数据是会修改的,但是,因为没有 set 函数,无法监听到数据的改变,所以页面上是不会重新渲染修改后的属性值的。例如下图

 Vue-数组变更方法

那我需要改变数组且还能让Vue监听到重新渲染页面的话,又应该怎么办呢?对此,Vue 是这样考虑的。

Vue 收集了我们平时操作数组的方法,发现 push、pop、shift、unshift,splice,sort、reserve这七个操作数组的方法,都会对原数组产生影响,反之像 map、filter、some、every等数组遍历的方法都只是会产生一个新的数组,并不会对原数组产生影响。

所以 Vue 将这7个方法进行了处理,并规定如果调用了这七个操作数组的方法,那我的 Vue 才会去监听数据的改变,如果是map等方法,那你原数据都没有改变,我也不用监听了。所以,当我想去操作数组中的属性的时候,我们不能直接 通过序号来操作,而是需要调用数组的这七个方法,例如

 那又出现一个问题了,我调用了 push 这七个操作数组的方法之后,Vue 是怎么知道我调了的呢?这个时候我们把 hobbys 展开来看就能发现原因所在了

 因为 hobbys 也是一个数组,所以它的 prototype 是一个 Array。我们将它展开之后发现,上面挂载了 我们说的这七个操作数组的方法,所以说,当我们通过 vm._data.hobbys.push() 来操作数据的时候,实际上我们调用的是原型上自带的 push 方法,调用其他六个数组方法也是一样。

之前说过了 Vue 把这七个操作数组的方法进行了处理,实际上是Vue将这七个方法进行了包装,然后直接挂载到了Vue的数组原型对象上。所以,这七个方法和js自带的七个方法实际上是不一样的

那么 Vue 包装之后的这些方法里面又是怎么做的来让Vue实现对数据监听的呢?我们还是以push为例,当调用 vm中数组原型上的 push 方法之后,分别作了如下操作

        1、调用原生的 push方法,改变数组数据

        2、生成新的虚拟DOM,新旧虚拟DOM对比,模板编译、页面重新渲染

 那如果我们不使用这七个方法,就不能监听数据重新渲染了么?那肯定是不可能的,还记得上一章讲的 set 方法么,其实 set 也可以对数组使用,不过使用的很少就是了,具体使用方法:

 target:之前说了可以使用vm._data,但是因为Vue的数据代理,我们也可以简写成 vm

key:直接写需要改变的数据的索引值就行

value:需要改变的值

总结

1、Vue 监听数组改变,使用的是 数组的变更方法,包括:push、pop、shift、unshift、splice、sort、reserve,因为这七个方法操作数组之后,会改变原数组

2、这七个方法不是Array.prototype 上的方法,而是经过 Vue 的包装处理之后,挂载到Vue 的 Array.prototype 上的

3、同时也可以使用 set 方法,以此来改变当前数组,且Vue还能监听到,不过基本不这么使用

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐