手撕Vue-数据驱动界面改变中

经过上一篇的介绍,已经实现了观察者模式的基本内容,接下来要完成的就是将上一篇的发布订阅模式运用到 Nue 中,实现数据驱动界面改变。

在监听数据变化的章节当中,根据指定的区域和数据去编译渲染界面 这个步骤处,我写了一个注释,这个注释是这样的:第一步:给外界传入的所有数据都添加get/set方法,第二步就是在第一步的基础上,给所有属性都添加观察者对象,当数据发生变化时,发布订阅触发观察者对象的回调函数重新渲染界面。

先处理下 v-model 的情况,找到 CompilerUtil 中的 model 方法,将其修改添加观察者对象代码:

model: function (node, value, vm) {
    // 第二部:在第一次渲染的时候, 就给所有的属性添加观察者
    new Watcher(vm, value, (newValue, oldValue) => {
        node.value = newValue;
    });

    node.value = this.getValue(vm, value);
},

这样就完成了第二步,接下来第三步就是将当前属性的所有观察者对象都放到当前属性的发布订阅对象中管理起来

在创建观察者对象的时候,在构造函数当中,会调用 getOldValue 方法,会调用 CompilerUtil.getValue 方法,这个方法就是用于获取属性值的,在编译模板之前已经给所有属性添加了 get/set 方法,所以在获取属性值的时候,就会触发 get 方法,我们就可以在 get 方法中将当前属性的观察者对象添加到当前属性的发布订阅对象中管理起来。

在 Observer 类中的 defineRecative 方法中添加如下代码:

defineReactive(obj, attr, value) {
    this.observer(value);

    // 第三步:将当前属性的所有观察者对象都放到当前属性的发布订阅对象中管理起来
    // 创建属于当前属性的发布订阅对象
    let dep = new Dep();

    Object.defineProperty(obj, attr, {
        get() {
            Dep.target && dep.addSub(Dep.target);
            return value;
        },
        set: (newValue) => {
            if (value !== newValue) {
                this.observer(newValue);
                value = newValue;
                dep.notify();
                console.log('监听到数据的变化, 需要去更新UI');
            }
        }
    })
}

在上述代码中,创建了一个属于当前属性的发布订阅对象,然后在 get 方法中,判断 Dep.target 是否存在,如果存在,就将当前属性的观察者对象添加到当前属性的发布订阅对象中管理起来。Dep.target 就是当前属性的观察者对象,这里该需要在改造一下观察者的类,将观察者对象添加到 Dep.target 中,放在全局中管理起来。等到所有的属性都添加完观察者对象之后,就将 Dep.target 置为 null。

改造观察者类中的 getOldValue 方法, 这样在 get 方法中就可以将当前属性的观察者对象添加到当前属性的发布订阅对象中管理起来了:

getOldValue() {
    Dep.target = this;
    let oldValue = CompilerUtil.getValue(this.vm, this.attr);
    Dep.target = null;
    return oldValue;
}

这样就完成了数据驱动界面改变的功能,接下来我们就来测试一下,打开浏览器控制台,更改下数据,看看是否会触发界面的重新渲染,如下图所示:

image-20231015225532652

好了到此为止,我们已经完成了 v-model 数据驱动界面改变的功能。

下面我将以 debugger 的形式来讲解一下整个数据驱动界面改变的过程, 在 defineReactive get 方法中打上断点,如下图所示:

image-20231015225930152

返回浏览器,主要关注调用栈,如下图所示:

image-20231015230019559

自己从下依次往上看,就可以看到整个数据驱动界面改变的过程了,这里我就不一一截图了,大家可以自己去看一下。

image-20231015230130758

如上是 get 方法代码的执行流程,那么 set 的我也可以说明一下,set 方法的 debugger 不是打在 defineReactive 中,而是打在 Watcher 类中的 update 方法中,所执行的回调函数当中,如下图所示:

image-20231015230405011

返回浏览器,打开控制台更改数据触发 set 方法,发布订阅触发 update 方法:

image-20231015230617621

这次也是主要关注调用栈,自己从下依次往上看,就可以看到整个数据驱动界面改变的过程了,这里我就不一一截图了,大家可以自己去看一下,如下图所示:

image-20231015230547888

posted @   BNTang  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
  1. 1 总会有人离开 王巨星
  2. 2 月亮 孟凡明
  3. 3 迟里乌布
  4. 4 我只能离开 颜人中
  5. 5 达尔文 蔡健雅
  6. 6 夜色滚烫 叶明净
  7. 7 你的星环 路飞文
  8. 8 不再说话 三块木头
  9. 9 黄昏 粥粥和小伙/粥粥
  10. 10 爱不单行 刘大拿
  11. 11 心动贩卖机 PIggy
  12. 12 别来无恙 苏星婕
  13. 13 我们的歌 刘大拿
  14. 14 一直很安静 王贰浪
  15. 15 去有风的地方 清音
  16. 16 雪 Distance Capper/罗言
  17. 17 坏女孩 徐良/小凌
  18. 18 乐园 沧桑Cang333/虎皮蛋/曲甲
  19. 19 Ayo(Explicit) Chris Brown/Tyga
  20. 20 我的美丽feat.海洋Bo 海洋Bo/高睿
  21. 21 世事可爱 粥粥和小伙/粥粥
  22. 22 我记得 赵雷
  23. 23 我想牵着你的手 许嵩
  24. 24 人们都不懂 刘诺然
  25. 25 寻一个你(电视剧《苍兰诀》温情主题曲) TTTTTeehom
  26. 26 子莫格尼 杉和
  27. 27 Cat Cafe Shoffy
  28. 28 风停了雨停了我们还拥抱着 Superluckyqi
  29. 29 寂寞沙洲冷 于潼
  30. 30 三国恋 王巨星
  31. 31 达尔文 林俊杰
  32. 32 有些 颜人中
  33. 33 小模样 张小只ya
  34. 34 是否 程响
  35. 35 楼顶上的小斑鸠 队长
  36. 36 笑场 薛之谦
  37. 37 还是分开 张叶蕾
  38. 38 修炼爱情 林俊杰
  39. 39 二零三 毛不易
  40. 40 雅俗共赏 许嵩
  41. 41 Serendipity 古瑞斯Graps/Zakiya晴子
  42. 42 就让这大雨全都落下·2023 刘大拿
  43. 43 老男孩 筷子兄弟
  44. 44 有何不可 许嵩
  45. 45 缓缓 杜宣达
  46. 46 好久不见 陈奕迅
  47. 47 爱的魔法(Cover 金莎) 封茗囧菌
  48. 48 在你的身边 盛哲
  49. 49 带我去找夜生活 告五人
  50. 50 假面舞会 很美味
  51. 51 STAY The Kid LAROI/Justin Bieber
  52. 52 我好想睡觉的 无敌西红柿
  53. 53 日不落(温柔版)
  54. 54 恋爱画板 锦零
  55. 55 7710 好乐无荒/尹露浠
  56. 56 给你呀(又名:for ya) 蒋小呢
  57. 57 Love Story Taylor Swift
  58. 58 Plain Jane(Remix 13z) 鱼幼微
  59. 59 晚风 7opy/BT07
  60. 60 拜托 孙晨
  61. 61 乌梅子酱 李荣浩
  62. 62 南半球与北海道 范倪Liu
  63. 63 星河万里 Rom邢锐
有些 - 颜人中
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 李天阳

作曲 : 郑国锋

编曲 : 余竑龙

房间还是乱糟糟

外套还丢在一角

你搬走之后 我也没改变多少

藏着关心的打扰

简讯平静的语调

你说还好 抱着枕头也能睡着

Oh 好像是我的错

再多一个拥抱

我不再放掉

难过夹带陌生 的感觉 有一些

已模糊的镜头 拉不回 那从前

明明不是下雨天

却淋湿双眼

与你有关的泪点

又闪回到昨天 的错觉 有一些

你占据我世界 却不在 身边

我试着把抱歉 再说一遍

你 还是说了再见

房间还是乱糟糟

外套还丢在一角

你搬走之后 我也没改变多少

藏着关心的打扰

简讯平静的语调

你说还好 抱着枕头也能睡着

Oh 好像是我的错

再多一个拥抱

我不再放掉

难过夹带陌生 的感觉 有一些

已模糊的镜头 拉不回 那从前

明明不是下雨天

却淋湿双眼

与你有关的泪点

又闪回到昨天 的错觉 有一些

你占据我世界 却不在 身边

我试着把抱歉 再说一遍

你 还是说了再见

和你的照片还留着

笑中带泪是我输了

剩下弃权的选择

难过夹带陌生 的感觉 有一些

已模糊的镜头 拉不回 那从前

明明不是下雨天

却淋湿双眼

与你有关的泪点

又闪回到昨天 的错觉 有一些

你占据我世界 却不在 身边

我试着把抱歉 再说一遍

你 还是说了再见

制作人:余竑龙

执行制作:卢昌平

配唱:余竑龙

合声编写:郁采真

吉他:黄德霖/卢昌平

貝斯:卢昌平

混音:余竑龙

点击右上角即可分享
微信分享提示