vue 数组 指定位置添加数据_VUE 响应式原理源码:带你一步精通 VUE

4183972ec14785244332461fc63e692b.png

作者 | 爱编程的小和尚

责编 | 王晓曼

出品 | CSDN博客

学过 VUE 如果不了解响应式的原理,怎么能说自己熟练使用 VUE,要是没有写过一个简易版的 VUE 怎么能说自己精通 VUE,这篇文章通过300多行代码,带你写一个简易版的 VUE,主要实现 VUE 数据响应式 (数据劫持结合发布者-订阅者)、数组的变异方法、编译指令,数据的双向绑定的功能。

本文需要有一定 VUE 基础,并不适合新手学习。

文章较长,且有些难度,建议大家,找一个安静的环境,并在看之前沐浴更衣,保持编程的神圣感。下面是实现的简易版VUE 的源码地址,一定要先下载下来!因为文章中的并非全部的代码。

Github源码地址:https://github.com/young-monk/myVUE.git

57175186103749a5ff8bff994f8bb52b.png

前言

在开始学习之前,我们先来了解一下什么是 MVVM ,什么是数据响应式。

我们都知道 VUE 是一个典型的 MVVM 思想,由数据驱动视图。

那么什么是 MVVM 思想呢?

MVVM是Model-View-ViewModel,是把一个系统分为了模型( model )、视图( view )和 view-model 三个部分。

VUE在 MVVM 思想下,view 和model 之间没有直接的联系,但是 view 和 view-model 、model和 view-model之间时交互的,当 view 视图进行 dom 操作等使数据发生变化时,可以通过 view-model 同步到 model 中,同样的 model 数据变化也会同步到 view 中。

那么实现数据响应式都有什么方法呢?

1、发布者-订阅者模式:当一个对象(发布者)状态发生改变时,所有依赖它的对象(订阅者)都会得到通知。通俗点来讲,发布者就相当于报纸,而订阅者相当于读报纸的人。

2、脏值检查:通过存储旧的数据,和当前新的数据进行对比,观察是否有变更,来决定是否更新视图。angular.js 就是通过脏值检查的方式。最简单的实现方式就是通过 setInterval() 定时轮询检测数据变动,但这样无疑会增加性能,所以, angular 只有在指定的事件触发时进入脏值检测。

3、数据劫持:通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时触发相应的方法。

VUE是如何实现数据响应式的呢?

VUE.js 则是通过数据劫持结合发布者-订阅者模式的方式。

当执行 new VUE() 时,VUE 就进入了初始化阶段,VUE会对指令进行解析(初始化视图,增加订阅者,绑定更新函数),同时通过 Obserber会遍历数据并通过 Object.defineProperty 的 getter 和 setter 实现对的监听, 当数据发生变化的时候,Observer 中的 setter 方法被触发,setter 会立即调用Dep.notify(), Dep 开始遍历所有的订阅者,并调用订阅者的 update 方法,订阅者收到通知后对视图进行相应的更新。

我来依次介绍一下图中的重要的名词

1、Observer:数据监听器,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者,内部采用 Object.defineProperty 的 getter 和 setter 来实现

2、Compile:指令解析器,它的作用对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数

3、Dep:订阅者收集器或者叫消息订阅器都可以,它在内部维护了一个数组,用来收集订阅者,当数据改变触发 notify 函数,再调用订阅者的 update 方法

4、Watcher:订阅者,它是连接 Observer 和 Compile 的桥梁,收到消息订阅器的通知,更新视图

5、Updater:视图更新

所以我们想要实现一个 VUE 响应式,需要完成数据劫持、依赖收集、 发布者订阅者模式。

下面我来介绍我模仿源码实现的功能:

1、数据的响应式、双向绑定,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者

2、解析 VUE 常用的指令 v-html,v-text,v-bind,v-on,v-model,包括( @ 和 : )

3、数组变异方法的处理

4、在 VUE 中使用 this 访问或改变 data 中的数据

我们想要完成以上的功能,需要实现如下类和方法:

1、实现 Observe r类:对所有的数据进行监听

2、实现 array 工具方法:对变异方法的处理

3、实现 Dep 类:维护订阅者

4、实现 Watcher 类:接收 Dep 的更新通知,用于更新视图

5、实现 Compile 类:用于对指令进行解析

6、实现一个 CompileUtils 工具方法,实现通过指令更新视图、绑定更新函数Watcher

7、实现 this.data 代理:实现对 this. data 代理:实现对 this.data 代理:实现对 this.data 代理,可以直接在 VUE 中使用 this 获取当前数据

我是使用了webpack作为构建工具来协同开发的,所以在我实现的VUE响应式中会用到ES6模块化,webpack的相关知识。

2dde0148a307515606852f2450836830.png

实现 Observer 类

我们都知道要用 Obeject.defineProperty() 来监听属性的数据变化,我们需要对 Observer 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter ,这样的话,当给这个对象的某个值赋值,就会触发 setter,那么就能监听到

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值