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

yizhihongxing

详解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 cli3.x打包后如何修改生成的静态资源的目录和路径

    要修改Vue Cli 3.x生成的静态资源的目录和路径,步骤如下: 打开 vue.config.js 文件,如果没有该文件则需要手动创建,该文件需要放在项目根目录下。 在该文件中添加如下代码: module.exports = { publicPath: ‘./your-path/’ } 其中,publicPath 表示静态资源的目录和路径,./your-p…

    Vue 2023年5月27日
    00
  • 详解vue2.0的Element UI的表格table列时间戳格式化

    下面是详解vue2.0的Element UI的表格table列时间戳格式化的完整攻略。 1. 前言 Element UI是一款基于Vue.js 2.0的框架,它提供了丰富、灵活、高效的前端组件,其中表格(table)组件是应用非常广泛的一个组件,但是默认情况下,它的时间戳列(指Unix时间戳)显示的是毫秒数,不太友好。那么,我们该如何对Element UI的…

    Vue 2023年5月29日
    00
  • vue3中如何使用ref和reactive定义和修改响应式数据(最新推荐)

    在 Vue3 中,我们可以使用 ref 和 reactive API 来定义和修改响应式数据。 使用 ref ref API 用于定义一个基本数据类型的响应式数据,例如数字、字符串、布尔值等。下面是一个例子: import { ref } from ‘vue’; const count = ref(0); // 定义一个名为 count 的响应式数据,初始值…

    Vue 2023年5月27日
    00
  • 关于Dart中的异步编程

    我来为您详细讲解“关于Dart中的异步编程”。 异步编程简介 在编写程序时,我们通常会遇到一些需要等待的操作,例如网络请求、文件读取等,这些操作需要耗费时间。如果在这些操作执行完之前,程序阻塞在这里不继续执行,就会导致程序的性能下降,用户的体验变差。这时,我们通常会采用异步编程的方式来解决这个问题。 异步编程基于事件循环机制,通过回调函数的方式,在等待操作完…

    Vue 2023年5月28日
    00
  • vue-cli npm如何解决vue项目中缺失core-js的问题

    当我们创建一个Vue项目时,通常会使用vue-cli来进行项目初始化和配置。但是,在某些情况下,会在编译或运行Vue应用程序期间遇到缺少“core-js”的错误。这时,我们可以使用npm来安装“core-js”,以解决这个问题。 下面是解决“vue-cli npm如何解决vue项目中缺失core-js的问题”的完整攻略: 步骤1:检查缺少“core-js”的…

    Vue 2023年5月28日
    00
  • 详解vue-cli项目中用json-sever搭建mock服务器

    下面是详解“详解vue-cli项目中用json-sever搭建mock服务器”的完整攻略: 一、什么是json-server JSON Server是一个基于Node.js的RESTful API服务器,可以通过在本地运行json文件中的数据创建完整的RESTful API,这在前端开发中用于测试和模拟数据非常有帮助。 二、在Vue-cli项目中安装json…

    Vue 2023年5月28日
    00
  • vue导出excel表格的新手详细教程

    下面是“vue导出excel表格的新手详细教程”的完整攻略: 1. 安装依赖 首先,我们需要安装两个依赖包,file-saver和xlsx,分别用于文件保存和Excel表格的生成: npm install file-saver xlsx –save 2. 生成Excel文件 在Vue组件中,我们创建一个可以导出表格数据的方法,该方法需要调用xlsx库中的u…

    Vue 2023年5月27日
    00
  • 3分钟迅速学会Vue中methods方法使用技巧

    3分钟迅速学会Vue中methods方法使用技巧 简介 在Vue组件里,methods方法是非常重要的一部分,它是用来存放组件内部方法的地方。在使用Vue的时候,熟练掌握methods的使用技巧,能够提高开发速度和代码可读性。 基本使用方法 在Vue组件中,我们可以定义多个methods方法,类似于下面的例子: <template> <di…

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