Vue源码学习之关于对Array的数据侦听实现

yizhihongxing

这里提供一份 Vue 源码学习关于对 Array 数据侦听实现的完整攻略。

概述

Vue 框架作为数据驱动的 MVVM 框架,在响应式数据更新时能够实现高效的性能优化,是设计优秀的前端框架之一。而在 Vue 的响应式系统中,“对数组的数据侦听”是一个重要的实现细节,它可以实现监听数组数据变化并动态的更新视图。这也是 Vue 与其他前端框架的一个区别。

数组侦听实现

在 Vue 中,对于需要侦听的对象,会通过 Object.defineProperty 方法 实现属性拦截,从而实现对该对象的监听。而对于数组,则通过重写数组的原型方法来实现对数组数据的侦听。

源码分析

首先,Vue 在初始化时会先判断是否支持使用原生 __proto__ 属性。如果支持,Vue 会直接重写原型方法;否则,Vue 会创建一个新的对象,并将需要重写的数组原型方法挂载在该对象上,最后在数组对象上重新设置 __proto__ 属性;

接着,针对要被重写的 原型方法 pushpopshiftunshiftsplicesortreverse,Vue对这些数组方法增加了一个或多个拦截器。如 push 方法如下:

// src/core/observer/array.js

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

const methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
];

// 对数组对象的7个变异方法,添加拦截器
methodsToPatch.forEach(function (method) {
  // 原始方法
  const original = arrayProto[method];
  // 覆盖数组原型方法
  def(arrayMethods, method, function mutator (...args) {
    const result = original.apply(this, args);
    const ob = this.__ob__;
    let inserted;
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args;
        break;
      case 'splice':
        inserted = args.slice(2);
        break;
    }
    // 对插入的新元素进行响应式处理
    if (inserted) ob.observeArray(inserted);
    // 通知依赖更新
    ob.dep.notify();
    return result;
  });
});

我们可以看到,Vue 重写了数组的原型方法,并为数组的7个变异方法添加了拦截器。拦截器会拦截数组变化并进行响应式更新,通知依赖更新。

示例说明

我们来看一下一个实际的示例,这个示例是一个模板引擎库的源码(我翻译了一下),它基于 Vue 实现。在模板引擎中,我们可以使用 JavaScript 表达式,包括用于处理数组的方法。在下面的示例中,我们可以看到如何使用数组的 splice 方法来删除数组中的项:

<template>
  <ul>
    <li v-for="(item, index) in list" :key="index">{{ item }}</li>
  </ul>
  <button @click="deleteLastItem()">删除最后一个元素</button>
</template>

<script>
export default {
  data() {
    return {
      list: ['苹果', '香蕉', '草莓']
    }
  },
  methods: {
    deleteLastItem() {
      this.list.splice(this.list.length-1, 1)
    }
  }
}
</script>

上述示例中,我们使用 splice 方法从 list 数组中删除最后一个元素,删除后,Vue 会自动检测到该数组的数据变化,并执行相应的更新。

再来看一个使用 push 方法添加一个项的示例:

<template>
  <button @click="addItem()">添加元素到数组中</button>
  <div>
    {{ list }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: []
    }
  },
  methods: {
    addItem() {
      this.list.push('新加入的元素')
    }
  }
}
</script>

我们可以通过上述示例看到,当我们使用 push 方法添加新项时,Vue 同样会自动响应式更新视图。

总结

通过以上分析,我们可以看出 Vue 在对数组进行操作时,会重写数组的原型方法,并在方法内添加响应式逻辑。这种方式能较为高效地实现局部更新,且在我们在使用 Vue 的过程中,我们可以像普通数组一样正常使用其方法,并且能自动地触发相应的更新,这也是 Vue 响应式能力的重要部分之一。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue源码学习之关于对Array的数据侦听实现 - Python技术站

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

相关文章

  • el-date-picker日期范围限制的实现

    下面我来详细讲解“el-date-picker日期范围限制的实现”的完整攻略。 创建日期范围限制的实现 在实现日期范围限制之前,需要使用 Element UI 中的 el-date-picker 组件来创建日期选择器。el-date-picker 组件可通过 picker-options 属性来设置自定义的配置项,从而实现日期范围限制。 <templa…

    Vue 2023年5月29日
    00
  • 教你如何编写Vue.js的单元测试的方法

    如何编写 Vue.js 的单元测试 单元测试是软件开发过程中必不可少的环节之一,它可以保证代码的可靠性和健壮性,让开发者能够更加自信地改进和调试代码。在 Vue.js 中,我们可以使用一些框架和工具来编写单元测试,例如 Jest、Vue Test Utils 等。本文将详细介绍如何编写 Vue.js 的单元测试。 1. 安装 Jest Jest 是一个流行的…

    Vue 2023年5月27日
    00
  • Vue Element前端应用开发之整合ABP框架的前端登录

    Vue Element前端应用开发之整合ABP框架的前端登录攻略 1. 注册ABP React网站并获取认证密钥 首先,我们需要先注册ABP React(或Vue)网站,并获取相应的认证密钥。具体步骤如下:1. 进入 https://react.aspnetboilerplate.com/ (或者 https://vue.aspnetboilerplate.…

    Vue 2023年5月28日
    00
  • 爬虫代理的cookie如何生成运行

    如果使用爬虫代理访问需要登录的网站,必须要使用相应的登录凭证来进行访问。其中,cookie是一种常见的登录凭证。通过设置正确的cookie,可以模拟已登录的状态进行网站访问。下面是一个关于如何在使用爬虫代理时生成cookie的攻略。 步骤一:获取登录凭证 要生成cookie,首先需要获取正确的登录凭证,例如用户名和密码。其中,这些凭证可能需要从数据库或者文件…

    Vue 2023年5月28日
    00
  • Vue中的循环及修改差值表达式的方法

    下面我会详细讲解Vue中循环及修改差值表达式的方法的完整攻略。 循环列表 在Vue中,我们可以使用v-for指令来遍历数组或对象,并渲染出每一个元素。下面是一个简单的例子,展示了如何通过v-for指令来循环遍历数组并渲染每一个元素。 <template> <div> <h2>循环列表</h2> <ul&g…

    Vue 2023年5月29日
    00
  • 一文详解Vue选项式 API 的生命周期选项和组合式API

    一文详解Vue选项式 API 的生命周期选项和组合式API 前言 Vue 3.0 正式版发布后,options API 和 composition API 成为开发者最热门的讨论话题。Options API 是 Vue 2.x 默认使用的 API,而在 Vue 3.0 中引入了 Composition API,可谓是 Vue 3.0 的一大亮点。两种 API…

    Vue 2023年5月29日
    00
  • vue+node+webpack环境搭建教程

    Vue + Node + Webpack 环境搭建教程 本文详细讲解如何搭建 Vue + Node + Webpack 环境,以及相关的配置和注意事项。本教程中使用的框架版本如下: Vue.js:2.x Node.js:8.x Webpack:3.x 1. 安装 Node.js 在开始搭建前,首先需要安装 Node.js。Node.js 是一个基于 Chro…

    Vue 2023年5月27日
    00
  • 解决vue-cli中stylus无法使用的问题方法

    下面是完整的“解决vue-cli中stylus无法使用的问题方法”的攻略。 问题描述 在使用vue-cli创建Vue项目的过程中,通过命令行工具安装完stylus插件后,却无法使用stylus的语法。 原因分析 vue-cli默认并未安装stylus插件,因此如果要在Vue项目中使用stylus,需要先通过npm或者yarn等包管理工具手动安装stylus插…

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