文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

Vue2响应式系统之深度响应怎么实现

2023-06-30 01:40

关注

本文小编为大家详细介绍“Vue2响应式系统之深度响应怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue2响应式系统之深度响应怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

1、场景

import { observe } from "./reactive";import Watcher from "./watcher";const data = {    text: {        innerText: {            childText: "hello",        },    },};observe(data);const updateComponent = () => {    console.log(data.text.innerText.childText);};new Watcher(updateComponent);data.text.innerText.childText = "liang";

我们的响应式系统到现在还没有支持属性是对象时候的响应,因此我们改变 的时候不会有任何输出。childText

我们只收集了 的依赖,所以如果想要响应的话必须给 整个赋值为一个新对象。data.textdata.text

import { observe } from "./reactive";import Watcher from "./watcher";const data = {    text: {        innerText: {            childText: "hello",        },    },};observe(data);const updateComponent = () => {    console.log(data.text.innerText.childText);};new Watcher(updateComponent);data.text = {    innerText: {        childText: "liang",    },};

Vue2响应式系统之深度响应怎么实现

我们当然不希望每次都赋值整个对象,我们需要做一些修改,把嵌套的对象也变成响应式的。

2、方案

我们只需要在给某个 重写 和 之前,把它的 就像上边给 调用 函数一样,也调用一次 函数即可。keygetsetvaluedataobserveobserve

同时提供 参数,留下扩展,让外界决定是否需要深度响应。shallow

export function defineReactive(obj, key, val, shallow) {    const property = Object.getOwnPropertyDescriptor(obj, key);    // 读取用户可能自己定义了的 get、set    const getter = property && property.get;    const setter = property && property.set;    // val 没有传进来话进行手动赋值    if ((!getter || setter) && arguments.length === 2) {        val = obj[key];    }    const dep = new Dep(); // 持有一个 Dep 对象,用来保存所有依赖于该变量的 Watcher        !shallow && observe(val);      Object.defineProperty(obj, key, {        enumerable: true,        configurable: true,        get: function reactiveGetter() {            const value = getter ? getter.call(obj) : val;            if (Dep.target) {                dep.depend();            }            return value;        },        set: function reactiveSetter(newVal) {            const value = getter ? getter.call(obj) : val;            if (setter) {                setter.call(obj, newVal);            } else {                val = newVal;            }            dep.notify();        },    });}

同时,在 函数中,传进来的 不是对象的话我们直接 。observevaluereturn

export function observe(value) {    if (!isObject(value)) {        return;    }    let ob = new Observer(value);    return ob;}

3、场景2

import { observe } from "./reactive";import Watcher from "./watcher";const data = {    text: {        innerText: {            childText: "hello",        },    },};observe(data);const updateComponent = () => {    console.log(data.text.innerText.childText);};new Watcher(updateComponent);data.text.innerText.childText = "liang";data.text = {    innerText: {        childText: "liang2",    },};data.text.innerText.childText = "liang3";

可以一分钟想一下上边会输出什么。

new Watcher(updateComponent); ,执行一次 输出 。updateComponenthello

data.text.innerText.childText = "liang"; ,我们已经解决了属性是对象的情况,因此这里也会输出 。liang

data.text = {    innerText: {        childText: "liang2",    },};

上边代码就是文章最开头的方法,因此也会触发函数执行,输出 。liang2

data.text.innerText.childText = "liang3"; 最后这句会执行吗?

答案是否定的了,因为我们的 赋值为了一个新对象,但这个新对象我们并没有将其设置为响应式的。data.text

因此我们需要在 的时候把对象也设置为响应式的。set

export function defineReactive(obj, key, val, shallow) {    const property = Object.getOwnPropertyDescriptor(obj, key);    // 读取用户可能自己定义了的 get、set    const getter = property && property.get;    const setter = property && property.set;    // val 没有传进来话进行手动赋值    if ((!getter || setter) && arguments.length === 2) {        val = obj[key];    }    const dep = new Dep(); // 持有一个 Dep 对象,用来保存所有依赖于该变量的 Watcher    let childOb = !shallow && observe(val);    Object.defineProperty(obj, key, {        enumerable: true,        configurable: true,        get: function reactiveGetter() {            const value = getter ? getter.call(obj) : val;            if (Dep.target) {                dep.depend();            }            return value;        },        set: function reactiveSetter(newVal) {            const value = getter ? getter.call(obj) : val;            if (setter) {                setter.call(obj, newVal);            } else {                val = newVal;            }                      childOb = !shallow && observe(newVal);                       dep.notify();        },    });}

读到这里,这篇“Vue2响应式系统之深度响应怎么实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

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

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

软考中级精品资料免费领

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

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

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

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

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

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

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