返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue模拟响应式原理底层代码实现的示例
  • 663
分享到

Vue模拟响应式原理底层代码实现的示例

2024-04-02 19:04:59 663人浏览 泡泡鱼
摘要

目录1.vue.js功能:2.Observer.js功能(数据劫持):3.Compiler.js功能:4.Dep.js功能:5.Watcher.js功能:整体分析Vue的基本结构如下

整体分析Vue的基本结构如下图所示:(备注:完整代码GitHub地址https://github.com/1512955040/MiniVue)


上图中,为我们模拟最小vue的整体结构,首先创建一个vue类型,它负责把data中的成员注入到vue实例中,并且转化成getter/setter,observer的作用是数据劫持,对data中的属性进行数据监听,如果数据发生变化会获取到最新的值,并通知dep。Compiler的作用是解析每个元素中的指令和差值表达式并替换成相应的数据。Dep的作用是添加观察者,当数据发生变化时通知所有的观察者。Watcher内部有一个Update方法负责更新视图,下面我们用代码的方式一一进行实现。

1.Vue.js功能:

1-1负责接收初始化的参数(选项)

1-2负责把data中的属性注入到vue实例,转化成getter/setter

1-3负责调用observer监听data中所有属性的变化

1-4负责调用Compiler解析指令/差值表达式

类图结构如下:

如上图所示:vue类中有三个属性,分别是$options,$el,$data,这三个属性记录构造函数中传过来的参数。_proxyData为vue类中的方法

所以以_开头的成员就是私有成员,这个方法的功能是把data中的属性转化为getter和setter注入到vue实例中。


class Vue{
    constructor(options) {
        //1.通过属性保存选项中的数据
        this.$options = options || {}
        this.$data = options.data || {}
        this.$el = typeof options.el === 'string' ? document.querySelector(options.el) : options.el
        //2.把data中的成员转化为getter和setter,注入到vue实例中
        this._proxyData(this.$data)
        //3.调用observer对象,监听数据的变化
        new Observer(this.$data)
        //4.调用compiler对象,解析指令和差值表达式
        new Compiler(this)
    }
    //把Vue的属性转化为getter和setter,注入到Vue实例中
    _proxyData(data){
        //遍历data中所有属性
        Object.keys(data).forEach(key=>{
          //把data的属性注入到vue实例全局中
          Object.defineProperty(this,key,{
              enumerable:true,
              configurable:true,
              get(){
                return data[key]
              },
              set(newValue){
                if(newValue===data[key]){
                    return 
                }
                data[key]=newValue
             }
        })    
      })
    }
}

2.Observer.js功能(数据劫持):

2-1 负责把data选项中的属性转化为响应式数据

2-2 data中的某个属性也是对象,把该属性转化为响应式数据

2-3 数据变化发送通知

类图结构如下:

如上图所示:

walk方法的作用是遍历data中的所有属性,defineReactive是定义响应式数据,也就是通过调用defineReactive方法把属性转化为getter和setter。


class Observer{
    constructor(data) {
        this.walk(data)
    }
    //walk方法遍历data中的所有属性
    walk(data) {
        //1.判断data是否对象
        if(!data || typeof data !=='object'){
            return 
        }
        //2.遍历data对象的所有属性
        Object.keys(data).forEach(key=>{
            this.defineReactive(data,key,data[key])
        })
    }
    //degineReactivce方法定义响应式数据 把属性转化为getter和setter
    defineReactive(obj,key,val) {
        let that=this
        // 负责收集依赖,并发送通知
        let dep=new Dep()
        //如果val传入对象的话也给对象里面的属性添加getter和setter方法
        this.walk(val)
        Object.defineProperty(obj,key,{
            enumerable:true,
            configurable:true,
            get(){
                // 收集依赖
                Dep.target && dep.addSub(Dep.target)
                return val
            },
            set(newValue){
                if(newValue==val){
                    return 
                }
                val=newValue
                //如果给属性重新赋值成对象,给对象里面的属性重新添加getter和setter方法
                //比如:历史数据vm.msg="Hello World" 修改之后vm.msg={a:'Hwllo World'}
                //再次调用此方法给vm.msg.a重新添加getter和setter方法
                that.walk(newValue)
                //发送通知
                dep.notify()
            }
        })
    }
}

3.Compiler.js功能:

3-1 负责编译模板,解析指令/差值表达式

3-2 负责页面的首次渲染

3-3 当数据变化后重新渲染视图

类图结构如下:

如上图所示:

el为构造函数传过来的options.el,vm是vue的实例,下面都是vm的方法,对DOM进行操作。compile方法内部遍历dom对象的所有节点,并且

判断这些节点是文本节点,如果是文本节点解析差值表达式,如果是元素节点解析指令,isTextnode和isElementNode方法判断是文本节点还

是元素节点。compileElement和compileText方法解析差值表达式和指令。isDirective这个方法判断元素属性是否是指令。

4.Dep.js功能:

4-1 收集依赖,添加观察者(watcher)

4-2 通知所有观察者

如上图所示:

在vue的响应式机制中,使用观察者模式来响应数据的变化,Dep的作用是收集依赖,在getter方法中收集依赖,在setter方法中通知依赖,每

一个响应式的属性都会场景一个Dep对象,负责收集所有依赖于该属性的地方,所有依赖于该属性的位置都会创建一个watcher对象,所以

Dep就是收集于该属性的watcher对象,使用setter方法去通知依赖,当属性发生变化时调用nodify方法去发送通知,然后调用watcher对象

的update方法。

类的机构如下图:

如上图所示:

subs是一个数组,存储dep中所有的watcher,addSub方法添加watcher,notify方法发布通知


class Dep{
    constructor() {
        //存储所有的观察者
        this.subs=[]
    }
    // 添加观察者
    addSub(sub){
        if(sub && sub.update) {
            this.subs.push(sub)
        }
    }
    //发送通知
    notify(){
        this.subs.forEach(sub =>{
            sub.update()
        })
    }
}

5.Watcher.js功能:

5-1 当数据变化触发依赖,dep通知所有的Watcher实例更新视图

5-2 自身实例化的时候往dep对象中添加自己

如上图所示:

data中的每一个属性都要创建一个Dep对象, 在收集依赖的时候把所有对象的watcher添加到dep对象的subs数组中,在setter对象中发送通

知,调用Dep对象的notify方法通知所有关联的watcher对象更新视图。

类图结构如下:

如上图所示:

update对象更新视图,cb回调函数,指明如何更新视图。在更新视图的时候需要一个属性key(data中的属性名称),oldvalue是key 对应的值。


class Watcher{
    constructor(vm,key,cb) {
        this.vm=vm
        //data中的属性名称
        this.key=key
        //回调函数负责更新视图
        this.cb=cb
        //把watcher对象记录到Dep类的静态属性target
        Dep.target =this
        //触发get方法,在get方法中会调用addSub
        this.oldValue=vm[key]
        Dep.target=null
    }
    //当数据发生变化时更新视图
    update(){
        let newValue=this.vm[this.key]
        if(this.oldValue === newValue){
            return
        }
        this.cb(newValue)
    }
}

下面通过这张图作整体流程的总结

到此这篇关于Vue模拟响应式原理底层代码实现的示例的文章就介绍到这了,更多相关Vue 响应式原理内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Vue模拟响应式原理底层代码实现的示例

本文链接: https://lsjlt.com/news/132658.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Vue模拟响应式原理底层代码实现的示例
    目录1.Vue.js功能:2.Observer.js功能(数据劫持):3.Compiler.js功能:4.Dep.js功能:5.Watcher.js功能:整体分析Vue的基本结构如下...
    99+
    2024-04-02
  • Vue响应式原理模拟实现原理探究
    目录前置知识数据驱动数据响应式的核心原理Vue 2.xVue 3.x发布订阅和观察者模式发布/订阅模式观察者模式Vue响应式原理模拟实现VueObserver对data中的属性进行监...
    99+
    2024-04-02
  • Vue数据响应式原理实例代码分析
    本文小编为大家详细介绍“Vue数据响应式原理实例代码分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue数据响应式原理实例代码分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。改造数据我们先来尝试写一个函数...
    99+
    2023-07-04
  • Spring AOP底层原理及代理模式实例分析
    这篇文章主要介绍“Spring AOP底层原理及代理模式实例分析”,在日常操作中,相信很多人在Spring AOP底层原理及代理模式实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”S...
    99+
    2023-06-30
  • SpringAOP的底层实现方式-代理模式
    目录1.1 静态代理1.2 动态代理1.2.1 JDK动态代理(必须有接口)1.2.2 CGlib动态代理在学习Spring的过程中,留下一下痕迹。 代理模式,其实就是让别人做同样的...
    99+
    2024-04-02
  • C++string底层框架模拟实现代码
    目录一、 前言 二、 浅拷贝与深拷贝优缺点1. 浅拷贝2. 深拷贝3. 深拷贝现代版4. 写时拷贝三、 string框架搭建1. 框架定义2. 构造函数3. 析构函数4. 赋值重载5...
    99+
    2024-04-02
  • Vue响应式原理的示例详解
    Vue 最独特的特性之一,是非侵入式的响应系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。聊到 Vue 响应式实现原理,众多开发者都知道实现...
    99+
    2024-04-02
  • vue-next响应式原理的示例分析
    这篇文章给大家分享的是有关vue-next响应式原理的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。预备知识无论是阅读这篇文章,还是阅读 vue-next 响应式模块的源...
    99+
    2024-04-02
  • Vue中响应式原理的示例分析
    这篇文章主要介绍了Vue中响应式原理的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Vue 嘴显著的特性之一便是响应式系统(reac...
    99+
    2024-04-02
  • Vue响应式原理与虚拟DOM如何实现
    本篇内容介绍了“Vue响应式原理与虚拟DOM如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是响应式系统在Vue中,我们可以使...
    99+
    2023-07-05
  • VUE响应式原理的实现详解
    目录总结前言 相信vue学习者都会发现,vue使用起来上手非常方便,例如双向绑定机制,让我们实现视图、数据层的快速同步,但双向绑定机制实现的核心数据响应的原理是怎么样的呢,接下来让我...
    99+
    2024-04-02
  • Go底层channel实现原理及示例详解
    目录概念:使用场景:底层数据结构:操作:创建发送接收关闭案例分析:概念: Go中的channel 是一个队列,遵循先进先出的原则,负责协程之间的通信(Go 语言提倡不要通过共享内存来...
    99+
    2024-04-02
  • Vue响应式原理Observer、Dep、Watcher的示例分析
    小编给大家分享一下Vue响应式原理Observer、Dep、Watcher的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧...
    99+
    2024-04-02
  • C++模拟实现vector的示例代码
    目录1.前言2.vector介绍3.vector模拟实现3.1 迭代器接口3.2 vector元素操作3. 3 构造与析构1.前言 大家在学习C++的时候一定会学到STL(标准模板库...
    99+
    2024-04-02
  • 一文彻底搞懂Vue的MVVM响应式原理
    目录前言Vue的MVVM原理创建一个html示例在MVue.js中创建MVue入口创建Compile1.处理元素节点compileElement(child)2.处理文本节点comp...
    99+
    2024-04-02
  • Java LongAdder类介绍、代码示例、底层实现原理及与分段锁的区别
    LongAdder介绍 LongAdder是Java并发包(java.util.concurrent)中的一个类,用于高效地实现多线程环境下的加法操作。 在多线程环境中,如果多个线程同时对同一个变量进...
    99+
    2023-09-06
    java jvm 开发语言
  • Vue源码学习defineProperty响应式数据原理实现
    目录准备工作第一步 对对象进行劫持第二步 修改取值方法第三步 深度属性劫持准备工作 接上文数据初始化完成之后,就可以对数据进行劫持。Vue2中对数据进行劫持采用了一个Api叫Obje...
    99+
    2024-04-02
  • C++中priority_queue模拟实现的代码示例
    目录priority_queue概述 priority_queue定义 priority_queue特点 构造函数 修改相关函数pushpop容量相关函数sizeempty元素访问相...
    99+
    2024-04-02
  • 微信小程序底层实现原理的示例分析
    这篇文章给大家分享的是有关微信小程序底层实现原理的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。  根据小程序开发文档-框架(https://mp.weixin.qq.com/debug/wxadoc/d...
    99+
    2023-06-26
  • Vuejs响应式原理的示例分析
    小编给大家分享一下Vuejs响应式原理的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!响应式原理> vuejs中的...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作