详解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.js实现的幻灯片功能示例

    让我来给你详细讲解“vue.js实现的幻灯片功能示例”的完整攻略。首先,我们需要安装Vue.js,并且建立一个基本的Vue.js应用。 安装Vue.js 安装Vue.js最简单的方法是使用npm (node package manager)。首先,安装node.js和npm,然后在命令行中输入以下内容: npm install vue 创建Vue.js应用 …

    Vue 2023年5月27日
    00
  • Vue中的vue-resource示例详解

    Vue中的vue-resource示例详解 什么是vue-resource vue-resource是一个Vue.js插件,用于通过XHR实用RESTful API。 安装和引用 安装: npm install vue-resource –save 引用: import VueResource from ‘vue-resource’ Vue.use(Vue…

    Vue 2023年5月28日
    00
  • 浅析vue给不同环境配置不同打包命令

    为了给不同环境配置不同的打包命令,我们必须先对 Vue CLI 进行配置。下面是详细攻略: 步骤一:安装 Vue CLI 首先,我们需要安装 Vue CLI。可以使用以下命令进行全局安装: npm install -g @vue/cli 安装完成之后,你可以使用以下命令检查是否安装成功: vue –version 如果看到类似以下输出,说明安装成功: @v…

    Vue 2023年5月28日
    00
  • nodejs如何读取文件二进制 前端响应blob或base64显示图片

    一、读取文件二进制 在Node.js中,要读取文件二进制,可以使用Node.js内置的fs模块。可以通过调用fs.readFile方法来读取文件并将其保存到Buffer中,然后将其转换为二进制字符串。 以下是一个简单的示例: const fs = require(‘fs’); fs.readFile(‘./image.jpg’, (err, image) =…

    Vue 2023年5月28日
    00
  • vue 的 Render 函数

    Vue 的 Render 函数是Vue.js中最为重要的一个概念之一。它是Vue.js实现动态渲染的核心技术之一,向用户提供了更加灵活的数据操作和视图渲染方法,能够极大提高Vue应用的性能和灵活性。在下面的内容中,我将详细讲解Vue的Render函数,包括定义、用法、参数及示例等相关内容。 1. 定义 Render函数是用来定义Vue中组件的虚拟DOM的函数…

    Vue 2023年5月27日
    00
  • Vue3响应式对象是如何实现的(2)

    首先需要提醒一下,这个题目是指“Vue3响应式对象是如何实现的”系列文章的第二篇,如果还没看过第一篇的话,建议先去看一下第一篇的内容。 Vue3的响应式系统在内部实现中使用了ES6的Proxy对象。下面我将从两个方面来详细介绍其中的细节。 Proxy的基本用法 Proxy是ES6的一个新特性,可以用来拦截对象的底层操作,比如读取属性、写入属性、删除属性等。它…

    Vue 2023年5月28日
    00
  • Vue Cli项目重构为Vite的方法步骤

    Vue Cli项目重构为Vite的方法步骤: 安装Vite 首先,需要通过npm或yarn来全局安装Vite。可以使用以下命令来安装: npm install -g vite 或 yarn global add vite 创建新的Vite项目 使用Vite创建新项目时,可以选择手动创建或使用预设模板。推荐使用预设模板来快速创建新项目。可用的预设模板包括Rea…

    Vue 2023年5月28日
    00
  • 解决vue cli3使用axios跨域问题

    下面我来详细讲解如何解决vue cli3使用axios跨域问题的完整攻略。 什么是跨域问题 在前后端分离的开发模式中,前端和后端往往不在同一个域名下,当我们在前端使用ajax或fetch等方法向后端发送请求时,如果请求的域名和当前页面的域名不同,就会遇到跨域问题。跨域问题是浏览器的一种安全措施,为了防止恶意网站伪造请求,限制了不同域名下的数据交换。 利用vu…

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