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知识库 -> vue3响应式原理 -> 正文阅读

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

在js这门垃圾语言中没有指针,所以我们引入响应式。

指针在好多种场景下都有极好的效应。如果可以确保指针安全的使用,
那么可以在递归时不必考虑返回值来向上传递递归结果,而可以操作指针来从外部获取变量的值。
同理,在vue中,如何进行数据驱动显示是一门难题。
vue创造性地利用观察者模式实现了一种类似于指针的效应...

原理图

在这里插入图片描述

说明

obj=>一个组件所需要的所有数据。
a:1,b:2=>只是列举例子。
有一只眼睛在观察着是否有人往map里面添加数据,
它总是负责管理和维护这个列表->观察者模式。
一旦这个属性的值发生改变,它就会通知所有view实现自己的update方法去更新自己的状态。

但是这种订阅是结点去订阅一个数据的一个属性。针对同一个对象发起的订阅未免也太片面了。假如所我们有多个数据,又该如何管理呢?

这个时候可以向上层去考虑。

在这里插入图片描述

/*
	进行一些值的修改
*/
function effect(){

}
const targetMap = new WeekMap();
/*
跟踪某个对象的某个属性的变化,类似于我订阅了这个东西,如果这个东西有变化,你负责触发。
@param: target 订阅的对象
@param: key 定义对象哪个属性
*/
function track(target,key){
	let depsMap = targetMap.get(target);
	if(!depsMap){
		targetMap.set(target,depsMap=new Map());
	}
	let dep = depsMap.get(key);
	if(!dep){
		depsMap.set(key,dep = new Set());
	}
	dep.add(effect);
}
/*
跟踪某个对象的某个属性去触发。实际上是负责更新所有这些update的一个方法。
@param: target 订阅的对象
@param: key 定义对象哪个属性
*/
function trigger(target,key){
	let depsMap = targetMap.get(target);
	if(!depsMap) return;
	let dep = depsMap.get(key);
	dep.forEach(effect=>effect());
}

在这里插入图片描述
因为es6引入了proxy和Reflect,所以vue3可以不用Object.defineProperty的方式去监听底层对象。我们之前的对象就可以使用proxy监听。

let obj = reactive({a:1,b:2});

/*
	@param:obj,需要对其属性产生reactive的对象。
	@return:obj 这个对象的代理对象。
*/
function reactive(obj){
	let handler = {
		get(o,prop,receive){
			return Reflect.get(o,prop,receive);
		}
		set(o,prop,value,receive){
			Reflect.set(o,prop,value,receive);
		}
	};
	return new Proxy(obj,handler);
}

这是基本的写法。
查看上图我们发现,我们想要在set时产生一个trigger,在get时产生一个track。
obj.a=1,先get,产生一个track。再set,产生一个trigger
console.log(obj.a)产生一个track。因为上文已经对其做过追踪,所以不会重复设置。

 const targetMap = new WeakMap();
        /*
        跟踪某个对象的某个属性的变化,类似于我订阅了这个东西,如果这个东西有变化,你负责触发。
        @param: target 订阅的对象
        @param: key 定义对象哪个属性
        */
        function track(target, key) {
            let depsMap = targetMap.get(target);
            if (!depsMap) targetMap.set(target, depsMap = new Map());
            let dep = depsMap.get(key);
            if (!dep) depsMap.set(key, dep = new Set());
            dep.add(effect);
        }
        /*
        跟踪某个对象的某个属性去触发。实际上是负责更新所有这些update的一个方法。
        @param: target 订阅的对象
        @param: key 定义对象哪个属性
        */
        function trigger(target, key) {
            let depsMap = targetMap.get(target);
            if (!depsMap) return;
            let dep = depsMap.get(key);
            dep.forEach(effect => effect());
        }
        let res = 0;
        /*
        	进行一些值的修改
        */
        function effect() {
            res = obj.a + obj.b;
        }
        var obj = reactive({
            a: 1,
            b: 2
        });
        init();

        function init() {
            effect();
            console.log(res);
            obj.a = 11;
            console.log(res);
            obj.b = 22;
            console.log(res);
            //reactive
        }
        /*
        	@param:obj,需要对其属性产生reactive的对象。
        	@return:obj 这个对象的代理对象。
        */
        function reactive(obj) {
            let handler = {
                get(o, prop, receive) {
                    track(o, prop);
                    return Reflect.get(o, prop, receive);
                },
                set(o, prop, value, receive) {
                    Reflect.set(o, prop, value, receive);
                    trigger(o, prop);
                }
            };
            return new Proxy(obj, handler);
        }
		//代码可以直接打开F12测试运行
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:14:48  更:2022-03-30 18:15:02 
 
开发: 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 4:39:37-

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