详解vue数据响应式原理之数组

详解Vue数据响应式原理之数组

什么是Vue数据响应式?

Vue.js是一款MVVM框架,它通过数据绑定和组件化来构建用户界面。Vue的核心是将DOM和数据进行绑定,当数据发生变化时,DOM会自动更新,这就是Vue的数据响应式。

数组响应式的特殊性

数组在JS中是引用类型,当我们对一个数组进行变更时,比如push、pop、splice等操作,Vue是无法检测这些变化的。因此Vue提供了一些特殊的方法来实现数组响应式,包括push、pop、shift、unshift、splice、sort、reverse这些方法。

这些方法都会触发数组的更新,也就是数组内部的_observer会进行notify,再更新对应的DOM。

数组响应式的实现原理

Vue在初始化时会对所有的data进行递归遍历,并使用Object.defineProperty方法将属性变为getter/setter。在通过getter获取属性值时,Vue会收集当前Watcher,并推到Dep.target中,当属性变化时,setter会通知Dep,再通知Watcher更新DOM。

具体到数组上,Vue并没有使用Object.defineProperty来劫持数组上的方法。因为数组的方法是可以通过索引位置修改数组的元素的值的,如果使用Object.defineProperty劫持方法,会导致更新的粒度过细,性能不好。

Vue在劫持数组方法时,使用了另外一种方法,即重写数组上的方法。Vue重写数组上的这些方法,仍旧执行原方法的逻辑,最后再手动触发数组的通知更新,比如触发 _observer.notify(),从而告知Watcher有更新了,Watcher就可以更新对应的DOM。

下面是Vue内部对数组的劫持方式的代码实现:

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
  // 缓存原始方法
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator (...args) {
    const result = original.apply(this, args)
    const ob = this._observer
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    ob.notify()
    return result
  })
})

通过重写数组上的这些方法,Vue就能够实现数组响应式了。

示例说明

下面给出两个示例来说明Vue数组响应式的实现方式。

push方法

当我们使用数组的push方法添加一个新元素时,Vue会先判断该数组是否为被劫持过的数组,然后再触发原生的push方法,最后再手动触发数组的通知更新。

const arr = []
const ob = arr._observer // 这里 ob 指的是数组被监测到的Observer实例对象

arr.push(1)
// 调用原生push方法后 arr 变成 [1],同时会手动触发 ob.notify(),通知所有Watcher更新对应的DOM

splice方法

当我们使用数组的splice方法删除一个元素时,Vue会先判断该数组是否为被劫持过的数组,然后再触发原生的splice方法,最后再手动触发数组的通知更新。

const arr = [1, 2, 3]
const ob = arr._observer // 这里 ob 指的是数组被监测到的Observer实例对象

arr.splice(1, 1)
// 调用原生splice方法后 arr 变成 [1, 3],同时会手动触发 ob.notify(),通知所有Watcher更新对应的DOM

以上就是Vue数组响应式的实现方式以及示例说明。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解vue数据响应式原理之数组 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • 解决vue下载后台传过来的乱码流的问题

    解决vue下载后台传过来的乱码流的问题可以分为以下几个步骤: 确认后台接口返回的数据是正确编码的,比如UTF-8。 在vue中通过axios等网络请求库获取数据时,设置responseType为’blob’,这样能保证我们得到的数据是二进制的。 通过FileReader读取二进制数据,并转换为String。 创建Blob对象,将转换后的String数据存入该…

    Vue 2023年5月28日
    00
  • vue.js父子组件传参的原理与实现方法 原创

    下面是关于“vue.js父子组件传参的原理与实现方法”的详细攻略: 一、原理 在Vue.js中,父子组件之间的传参可以使用props进行实现。子组件可以通过props接收父组件传递的数据,而父组件则可以动态地改变这些数据,并且这些数据的变化会自动反应到子组件中。 具体而言,实现父子组件间传参的原理是: 父组件向子组件传递数据,需要定义props属性并在子组件…

    Vue 2023年5月27日
    00
  • Vue集成three.js并加载glb、gltf、FBX、json模型的场景分析

    下面是针对”Vue集成three.js并加载glb、gltf、FBX、json模型的场景分析”的完整攻略,包括两个示例的说明。 Vue集成three.js并加载模型的场景分析 前言 Three.js是一个基于webgl开发的JavaScript 3D库,它能够让开发人员通过JS创建各种3D场景。同时,Vue则是一个较为流行的JavaScript开发框架,可以…

    Vue 2023年5月28日
    00
  • 关于vue-property-decorator的基础使用实践

    下面我将详细讲解“关于vue-property-decorator的基础使用实践”的完整攻略,以及两条示例说明。 什么是vue-property-decorator vue-property-decorator 是 Vue.js TypeScript 类组件的实用装饰器,它提供了一些诸如 @Prop、@Component 等装饰器,简化了我们对 Vue 组件…

    Vue 2023年5月27日
    00
  • 从零实现一个vue文件解析器

    下面我将详细讲解从零实现一个Vue文件解析器的完整攻略。Vue文件是一种用于Vue.js框架的组件定义文件,其中包含Vue组件的所有相关信息,例如template、script和style等标签。 Vue文件解析器的实现过程主要包括以下几个步骤: 解析Vue文件内容,提取template、script和style标签的内容; 将提取出来的template、s…

    Vue 2023年5月27日
    00
  • vue基础ESLint Prettier配置教程详解

    以下是“vue基础ESLint Prettier配置教程详解”的完整攻略。 什么是ESLint和Prettier ESLint是一个开源的JavaScript Lint工具,用于识别和报告代码中的模式。它支持ES6语法和JSX语法,并插件化。对于样式一致性和错误检查等非常有用。它可以直接集成到IDE中,可以在保存时自动进行formatting和代码规范的检查…

    Vue 2023年5月28日
    00
  • Vue中的文字换行问题

    当我们在 Vue 中渲染一段文本时,如果这段文本包含了换行符(\n),那么在页面中就不一定会正确地显示换行。这是因为 HTML 会自动忽略多余的空格和换行符。 要解决这个问题,我们可以使用以下三种方式: 1. 使用 <br> 标签 我们可以在文本中手动插入 <br> 标签,告诉浏览器在这里进行换行。示例代码如下: <templa…

    Vue 2023年5月27日
    00
  • Vue计时器的用法详解

    Vue计时器的用法详解 在Vue.js中,我们可以使用计时器来执行一些定时任务,比如实现一些定时更新视图、缓慢滚动等效果。本篇文章将介绍Vue计时器的使用方法。 setInterval和clearInterval 在JavaScript中,我们可以使用setInterval函数来创建计时器,该函数将在指定的时间间隔内执行回调函数。使用clearInterva…

    Vue 2023年5月29日
    00
合作推广
合作推广
分享本页
返回顶部