IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue2响应式原理 -> 正文阅读

[JavaScript知识库]vue2响应式原理

核心部件

Observer-观察者

作用: 将一个普通对象转换为一个响应式对象

响应式对象:简单来说就是每个属性都具有getter与setter方法的对象

实现原理: 遍历普通对象,通过Object.defineProperty方法重新定义普通对象中的每个属性,将其转化为响应式对象.数组对象,嵌套对象使用递归实现深层次遍历

该事件发生在beforeCreate与created之间

由于遍历时仅能遍历到对象的当前属性,因此无法检测到将来动态增加或者删除的属性,因此vue提供$set$delete两个实例方法对已有的响应式对象进行添加或删除属性,但是这两个方法很有可能会引发没有必要的重新渲染,所以vue并不怎么推荐使用,而是期望我们在定义对象时給属性一个默认值null或者别的值

对于数组: vue会更改其隐式原型__proto__,增加vue自己写的pop,push,shift,unshift,sort,reverse,splice方法,之所以这样做是因为vue需要监听那些可能改变数组内容的方法

数组原型链: 数组 — vue自定义对象 — Array.prototype

Observer终极目标: 让对象的任何操作都能受到Vue监控

如上Observer解决了属性变化会通知vue,让Vue做操作的问题
但是 vue用通知谁去做呢?又要去做什么呢?

Dep – Dependency – 依赖

作用: 解决两个问题
1 读取属性时去做什么
2 属性改变时去做什么

vue会为响应式对象中的每个属性,对象本身,数组本身创建一个Dep实例,每个实例都有能力做到两件事

  1. 记录依赖: 当响应式对象的属性被读取时,它会进行依赖收集,既是谁用到了我
  2. 派发更新: 当改变某个属性时,它会通知那些用到我的人,我改变了
    上述两点中的我指的是该属性,对象,或数组

Dep解决了Observer未能解决的做什么的问题,现在vue具有了能动态做事的能力,但是现阶段Dep实例只是知道去做事,还是不知道要谁去做事.

Watcher

作用: 完成闭环,解决是谁去做事的问题

拿render函数举例
ps: 不知道render函数的话去补补吧
render函数不会直接执行,而是交给Watcher去执行,在watcher要执行render之前,watcher将会在全局设置一个变量,并使其等于render,例如window.currentHandler = watcher.render(只是瞎举例),然后去执行函数render,当render执行过程中用到响应式数据,则会触发Dep实例的记录依赖功能,在这时,Dep会记录当前全局变量windowcurrentHandler的值,当Dep触发派发功能时,通知之前记录的watcher,响应式原理完成闭环
但是此时产生一个效率问题

//假设页面使用了a b c d四个属性
//一个函数foo修改四个属性
foo() {
	this.a = 1;
	this.b = 2;
	this.c = 3;
	this.d = 4;
}
//由于a b c d均为响应式数据, 此函数运行时会触发四次Dep的派发功能,
//也就是会触发四次watcher, 也就是会触发四次render函数,渲染四次页面,
//由此产生效率问题,那么如何解决呢?

Scheduler–调度器

作用: 解决效率问题
其实Watcher在收到派发通知的时候并不会立即去执行对应的函数,而是把自己交给调度器Scheduler

Scheduler维护一个执行队列,该队列同一个Watcher仅会存在一次该队列的Watcher不会立即执行,他会通过一个nextTick的工具方法,把需要执行的watcher放入到事件循环的微队列中,nextTick的具体做法师通过Promise完成的

nextTick工具会通过$nextTick暴露給开发者

也就是说,当响应式数据变化时,render函数的执行时异步的,并且在微队列中

不算太好理解,来搞个事情

<div id="app">
    <h1 id="test">{{ a }}, {{ b }}</h1>
    <button @click="changeSomething">改变</button>
</div>
<script>
const vm = new Vue({
    el: "#app",
    data() {
        return {
            a: 1,
            b: 2
        }
    },
    methods: {
        changeSomething() {
        	//例1
            this.$nextTick(()=> {
                let h1 = document.getElementById("test");
                console.log(h1.innerText); //打印 1, 2
                /*
					打印 1, 2 的原因是 scheduler维护一个微队列,nextTick中的函数
					已被放入此微队列
					this.a的修改触发的watcher放入微队列时被排在了后面
					所以执行时this.a this.b并没有被更改
				*/
            });
            this.a = 99;
            this.b = 100;
			// ---------------------------
			//例2
			// this.a = 99;
            // this.$nextTick(()=> {
            //     let h1 = document.getElementById("test");
            //     console.log(h1.innerText); //打印 99, 100
            		/*
            			this.a先执行,所以watcher已被放入微队列
            			nextTick中的函数放在后面
            			this.b执行时触发的是同一个watcher所以
            			没有新的watcher加在后面
            		*/
            // });
            // this.b = 100;
        }
    },
})
</script>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:22:38  更:2022-03-10 22:22:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:42:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码