文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue3响应式原理和api编写的方法是什么

2023-06-22 01:15

关注

这篇文章主要讲解了“vue3响应式原理和api编写的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue3响应式原理和api编写的方法是什么”吧!

前言

vue3响应式原理加api编写,快速明白vue3响应式原理

vue3响应式原理实现

先写一段代码看下

实现effect

var name = 'sl', age = 22;effect1 = () => `我叫${name},今年${age}岁`effect2 = () => `我叫${name},今年${age+1}岁`console.log(effect1()) //我叫sl,今年22岁console.log(effect2()) //我叫sl,今年23岁age = 30;console.log(effect1())  //我叫sl,今年30岁console.log(effect2())  //我叫sl,今年31岁

看看有什么可以优化的点呢?

首先:多个函数,在age发生变化后需要手动再次调用多个函数才可以获取最新信息

期望可以修改信息以后自动调用多个函数

如何实现呢

可以想到将多个函数存放到一起存放到gather函数,并且让age发生变化时可以将多个函数调用trigger调用

实现gather及trigger

var name = "sl",  age = 22;var tom, joy;effect1 = () => (tom = `我叫${name},今年${age}岁`);effect2 = () => (joy = `我叫${name},今年${age + 1}岁`);var dep = new Set();function gather() {  dep.add(effect1);  dep.add(effect2);}function trigger() {  dep.forEach((effect) => effect());}gather();effect1()effect2()console.log(tom); //我叫sl,今年22岁console.log(joy); //我叫sl,今年23岁age = 30;trigger()console.log(tom); //我叫sl,今年30岁console.log(joy); //我叫sl,今年31岁

再继续看下还是有什么可以优化的点

如果变量是一个对象或多个对象的话该怎么处理呢

var obj1 = { name: "tom", age: 22 };var obj2 = { name: "joy", age: 23 };var tom, joy;effect1 = () => (tom = `我叫${obj1.name},今年${obj1.age}岁`);effect2 = () => (joy = `我叫${obj2.name},今年${obj2.age}岁`);var depsMap = new WeakMap();function gather(target, key) {  let depMap = depsMap.get(target);  if (!depMap) {    depsMap.set(target, (depMap = new Map()));  }  let dep = depMap.get(key);  if (!dep) {    depMap.set(key, (dep = new Set()));  }  if (target === obj1) {    dep.add(effect1);  } else {    dep.add(effect2);  }}function trigger(target, key) {  let depMap = depsMap.get(target);  if (depMap) {    const dep = depMap.get(key);    if (dep) {      dep.forEach((effect) => effect());    }  }}gather(obj1, "age");//收集依赖gather(obj2, "age");//收集依赖effect1();effect2();console.log(tom); //我叫sl,今年22岁console.log(joy); //我叫sl,今年23岁obj1.age = 30;obj2.age = 10;trigger(obj1, "age");trigger(obj2, "age");console.log(tom); //我叫sl,今年30岁console.log(joy); //我叫sl,今年31岁

在继续看看有哪些可以优化的点

上边依赖的收集gather以及函数的更新通知trigger每次都是手动收集手动触发更新,那有什么方法可以自动收集及触发吗

Proxy

实现reactive

先写一个reactive函数

function reactive(target) {  const handle = {    set(target, key, value, receiver) {      Reflect.set(target, key, value, receiver);      trigger(receiver,key) // 设置值时触发自动更新    },    get(target, key, receiver) {      gather(receiver, key); // 访问时收集依赖      return Reflect.get(target, key, receiver);    },  };  return new Proxy(target, handle);}

然后将reactive函数应用到之前代码

var obj1 = reactive({ name: "tom", age: 22 });var obj2 = reactive({ name: "joy", age: 23 });var tom, joy;effect1 = () => (tom = `我叫${obj1.name},今年${obj1.age}岁`);effect2 = () => (joy = `我叫${obj2.name},今年${obj2.age}岁`);var depsMap = new WeakMap();function gather(target, key) {  let depMap = depsMap.get(target);  if (!depMap) {    depsMap.set(target, (depMap = new Map()));  }  let dep = depMap.get(key);  if (!dep) {    depMap.set(key, (dep = new Set()));  }  if (target === obj1) {    dep.add(effect1);  } else {    dep.add(effect2);  }}function trigger(target, key) {  let depMap = depsMap.get(target);  if (depMap) {    const dep = depMap.get(key);    if (dep) {      dep.forEach((effect) => effect());    }  }}effect1();effect2();console.log(tom); //我叫sl,今年22岁console.log(joy); //我叫sl,今年23岁obj1.age = 30;obj2.age = 10;console.log(tom); //我叫sl,今年30岁console.log(joy); //我叫sl,今年31岁

然后还有个问题,就是gather函数中有写死dep添加函数

如何解决呢 重写effect函数

let activeEffect = nullfunction effect(fn) {  activeEffect = fn;  activeEffect();  activeEffect = null; // 执行后立马变成null}var depsMap = new WeakMap();function gather(target, key) {  // 避免例如console.log(obj1.name)而触发gather  if (!activeEffect) return;  let depMap = depsMap.get(target);  if (!depMap) {    depsMap.set(target, (depMap = new Map()));  }  let dep = depMap.get(key);  if (!dep) {    depMap.set(key, (dep = new Set()));  }  dep.add(activeEffect) //将函数添加到依赖}effect(effect1);effect(effect2);

reactive也已经实现了,那么还有ref也实现下

ref

在vue3中ref怎么使用呢

var name = ref('tom')console.log(name.value) // tom

需要使用.value的方式获取值

function ref(name){    return reactive(        {            value: name        }    )}const name = ref('tom');console.log(name.value) //tom

完整代码

var activeEffect = null;function effect(fn) {  activeEffect = fn;  activeEffect();  activeEffect = null; }var depsMap = new WeakMap();function gather(target, key) {  // 避免例如console.log(obj1.name)而触发gather  if (!activeEffect) return;  let depMap = depsMap.get(target);  if (!depMap) {    depsMap.set(target, (depMap = new Map()));  }  let dep = depMap.get(key);  if (!dep) {    depMap.set(key, (dep = new Set()));  }  dep.add(activeEffect)}function trigger(target, key) {  let depMap = depsMap.get(target);  if (depMap) {    const dep = depMap.get(key);    if (dep) {      dep.forEach((effect) => effect());    }  }}function reactive(target) {  const handle = {    set(target, key, value, receiver) {      Reflect.set(target, key, value, receiver);      trigger(receiver, key); // 设置值时触发自动更新    },    get(target, key, receiver) {      gather(receiver, key); // 访问时收集依赖      return Reflect.get(target, key, receiver);    },  };  return new Proxy(target, handle);}function ref(name){    return reactive(        {            value: name        }    )}

感谢各位的阅读,以上就是“vue3响应式原理和api编写的方法是什么”的内容了,经过本文的学习后,相信大家对vue3响应式原理和api编写的方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯