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

这里提供一份 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日

相关文章

  • Vue面试必备之防抖和节流的使用

    当谈论Vue的面试必备技能时,防抖和节流的使用肯定是少不了的。在Vue开发中,我们经常需要对用户的输入进行 debounce(防抖) 或 throttle(节流) 的处理,以避免过度触发重压服务器,影响用户体验。那么,接下来我将详细讲解防抖和节流的使用以及如何在Vue中灵活运用这两个技术。 一、什么是防抖和节流? 1. 防抖 防抖是指在事件被触发n秒后再执行…

    Vue 2023年5月27日
    00
  • vue1.0和vue2.0的watch监听事件写法详解

    下面就来详细讲解Vue.js的watch监听事件写法。 什么是Vue.js的watch监听事件 在Vue.js中,watch监听是Vue实例中一个非常重要的属性。它可用于监控Vue实例数据的变化,并在数据变化时立即做出响应操作。 Vue.js的watch监听事件用于监控数据变化的情况下执行一些操作。比如:当数据变化时,需要向服务器发送请求,或根据数据变化对D…

    Vue 2023年5月29日
    00
  • vue 内置过滤器的使用总结(附加自定义过滤器)

    下面是详细讲解“vue 内置过滤器的使用总结(附加自定义过滤器)”的完整攻略,过程中将给出两个示例来说明。 1. vue 内置过滤器 Vue 提供了一些内置的过滤器,用于快速展示数据的不同格式。这些过滤器可以在插值表达式和 v-bind 指令中使用。 1.1 文本格式化 {{message | capitalize}}: 将信息的第一个字母大写。 {{mes…

    Vue 2023年5月27日
    00
  • vue实现前端列表多条件筛选

    下面是“vue实现前端列表多条件筛选”的完整攻略: 准备工作 首先需要引入Vue.js和element-ui组件库。除此之外,还需要一个数据列表和一个查询条件对象。 实现步骤 1. 查询条件的展示 使用element-ui组件库提供的Form组件渲染查询表单。每个查询条件使用FormItem包装,FormItem的label属性即为查询条件的名称,Prop属…

    Vue 2023年5月28日
    00
  • 简单聊一聊axios配置请求头content-type

    当使用axios发送HTTP请求时,你可以在请求中添加headers头部来指定Content-Type类型。默认情况下,Content-Type类型为application/json。这意味着在发送axios请求时,如果我们的请求需要使用不同的Content-Type设置,我们需要进行额外的配置。 下面是一份通用的axios请求配置,可以让我们设置请求头的C…

    Vue 2023年5月28日
    00
  • 详解Puppeteer前端自动化测试实践

    详解Puppeteer前端自动化测试实践 引言 前端自动化测试作为保证前端代码质量的重要手段,在现在的前端开发中已经非常普遍。而Puppeteer作为谷歌官方出品的一款自动化测试工具,其强大的能力受到了越来越多前端从业者的青睐。本文将详细讲解如何使用Puppeteer实现前端自动化测试。 Puppeteer简介 Puppeteer是一个基于Node.js的库…

    Vue 2023年5月28日
    00
  • Vue 实现双向绑定的四种方法

    当我们用Vue框架去编写一个前端应用时,往往需要实现双向绑定,这是Vue框架最重要的特性之一。Vue实现双向绑定的方式有很多,下面将详细讲解四种方法的具体实现过程和示例。 1. Object.defineProperty Object.defineProperty是一种实现双向绑定的最基础的方法,这种方法适用于所有支持ECMAScript5的浏览器。 实现双…

    Vue 2023年5月28日
    00
  • Vue 动画效果、过渡效果的示例代码

    下面是详细讲解Vue动画效果、过渡效果的示例代码的攻略。 准备工作 在开始讲解之前,需要保证已经安装好Vue.js框架。另外,为了方便案例演示,我们需要借助Vue的官方库vue-router完成路由跳转。 首先,我们需要创建Vue项目,在项目中安装vue-router: // 创建Vue项目 vue create my-project // 安装vue-ro…

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