我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Vue2响应式系统之嵌套怎么实现

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Vue2响应式系统之嵌套怎么实现

这篇“Vue2响应式系统之嵌套怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue2响应式系统之嵌套怎么实现”文章吧。

1、场景

在 开发中肯定存在组件嵌套组件的情况,类似于下边的样子。Vue

<!-- parent-component --><div>  <my-component :text="inner"></my-component>  {{ text }}<div><!-- my-component--><div>{{ text }}</div>

回到我们之前的响应式系统,模拟一下上边的情况:

import { observe } from "./reactive";import Watcher from "./watcher";const data = {    text: "hello, world",    inner: "内部",};observe(data);const updateMyComponent = () => {    console.log("子组件收到:", data.inner);};const updateParentComponent = () => {    new Watcher(updateMyComponent);    console.log("父组件收到:", data.text);};new Watcher(updateParentComponent);data.text = "hello, liang";

可以先 分钟考虑一下上边输出什么?1

首先回忆一下 会做什么操作。new Watcher

第一步是保存当前函数,然后执行当前函数前将全局的 赋值为当前 对象。Dep.targetWatcher

Vue2响应式系统之嵌套怎么实现

接下来执行 函数的时候,如果读取了相应的属性就会触发 ,从而将当前 收集到该属性的 中。gettergetWatcherDep

Vue2响应式系统之嵌套怎么实现

2、执行过程

import { observe } from "./reactive";import Watcher from "./watcher";const data = {    text: "hello, world",    inner: "内部",};observe(data);const updateMyComponent = () => {    console.log("子组件收到:", data.inner);};const updateParentComponent = () => {    new Watcher(updateMyComponent);    console.log("父组件收到:", data.text);};new Watcher(updateParentComponent);data.text = "hello, liang";

我们再一步一步理清一下:

  • new Watcher(updateParentComponent);

将 赋值为保存了 函数的 。Dep.targetupdateParentComponentWatcher

接下来执行 函数。updateParentComponent

  • new Watcher(updateMyComponent);

将 赋值为保存了 函数的 。Dep.targetupdateMyComponentWatcher

接下来执行 函数。updateMyComponent

const updateMyComponent = () => {    console.log("子组件收到:", data.inner);};// 读取了 inner 变量。// data.inner 的 Dep 收集当前 Watcher(保存了 `updateMyComponent` 函数)
const updateParentComponent = () => {    new Watcher(updateMyComponent);    console.log("父组件收到:", data.text);};// 读取了 text 变量。// data.text 的 Dep 收集当前 Watcher (保存了 `updateMyComponent` 函数)

data.text = "hello, liang";

触发 的 函数,执行它依赖的 ,而此时是 函数。textsetWatcherupdateMyComponent

所以上边代码最终输出的结果是:

子组件收到: 内部  // new Watcher(updateMyComponent); 时候输出
父组件收到: hello, world // new Watcher(updateParentComponent); 时候输出
子组件收到: 内部 // data.text = "hello, liang"; 输出

然而子组件并不依赖 ,依赖 的父组件反而没有执行。data.textdata.text

3、修复

上边的问题出在我们保存当前正在执行 时候使用的是单个变量 。WatcherDep.target = null; // 静态变量,全局唯一

回忆一下学习 语言或者汇编语言的时候对函数参数的处理:C

function b(p) {    console.log(p);}function a(p) {    b("child");    console.log(p);}a("parent");

当函数发生嵌套调用的时候,执行 函数的时候我们会先将参数压入栈中,然后执行 函数,同样将参数压入栈中, 函数执行完毕就将参数出栈。此时回到 函数就能正确取到 参数的值了。abbap

对应于 的收集,我们同样可以使用一个栈来保存,执行函数前将 压入栈,执行函数完毕后将 弹出栈即可。其中, 始终指向栈顶 ,代表当前正在执行的函数。WatcherWatcherWatcherDep.targetWatcher

回到 代码中,我们提供一个压栈和出栈的方法。Dep

import { remove } from "./util";let uid = 0;export default class Dep {    ... 省略}Dep.target = null; // 静态变量,全局唯一// The current target watcher being evaluated.// This is globally unique because only one watcher// can be evaluated at a time.const targetStack = [];export function pushTarget(target) {    targetStack.push(target);    Dep.target = target;}export function popTarget() {    targetStack.pop();    Dep.target = targetStack[targetStack.length - 1]; // 赋值为栈顶元素}

然后 中,执行函数之前进行入栈,执行后进行出栈。Watcher

import { pushTarget, popTarget } from "./dep";export default class Watcher {    constructor(Fn) {        this.getter = Fn;        this.depIds = new Set(); // 拥有 has 函数可以判断是否存在某个 id        this.deps = [];        this.newDeps = []; // 记录新一次的依赖        this.newDepIds = new Set();        this.get();    }        get() {              pushTarget(this); // 保存包装了当前正在执行的函数的 Watcher               let value;        try {            value = this.getter.call();        } catch (e) {            throw e;        } finally {                      popTarget();                      this.cleanupDeps();        }        return value;    }   ...}

4、测试

回到开头的场景,再来执行一下:

import { observe } from "./reactive";import Watcher from "./watcher";const data = {    text: "hello, world",    inner: "内部",};observe(data);const updateMyComponent = () => {    console.log("子组件收到:", data.inner);};const updateParentComponent = () => {    new Watcher(updateMyComponent);    console.log("父组件收到:", data.text);};new Watcher(updateParentComponent);data.text = "hello, liang";

执行 的时候将 入栈。new Watcher(updateParentComponent);Watcher

Vue2响应式系统之嵌套怎么实现

进入 函数,执行 的时候将 入栈。updateParentComponentnew Watcher(updateMyComponent);Watcher

Vue2响应式系统之嵌套怎么实现

执行 函数, 收集当前 ,执行完毕后 出栈。updateMyComponentdata.innerDep.targetWatcher

Vue2响应式系统之嵌套怎么实现

继续执行 函数, 收集当前 。updateParentComponentdata.textDep.target

此时依赖就变得正常了, 会触发 函数,从而输出如下:data.textupdateParentComponent

子组件收到: 内部
父组件收到: hello, world
子组件收到: 内部
父组件收到: hello, liang

以上就是关于“Vue2响应式系统之嵌套怎么实现”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

免责声明:

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

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

Vue2响应式系统之嵌套怎么实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Vue2响应式系统之嵌套怎么实现

这篇“Vue2响应式系统之嵌套怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue2响应式系统之嵌套怎么实现”文章吧
2023-06-30

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

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

Vue2响应式系统之异步队列怎么实现

这篇“Vue2响应式系统之异步队列怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue2响应式系统之异步队列怎么实现
2023-06-30

Vue2响应式系统之分支切换怎么实现

本篇内容介绍了“Vue2响应式系统之分支切换怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!场景我们考虑一下下边的代码会输出什么。im
2023-06-30

Vue2响应式系统之set和delete怎么用

今天小编给大家分享一下Vue2响应式系统之set和delete怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1、数组集
2023-06-30

Vue2响应式系统之怎么让数组生效

这篇文章主要介绍了Vue2响应式系统之怎么让数组生效的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue2响应式系统之怎么让数组生效文章都会有所收获,下面我们一起来看看吧。1、场景import { observ
2023-06-30

Vue2响应式系统有什么用

这篇文章主要讲解了“Vue2响应式系统有什么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue2响应式系统有什么用”吧!一、响应式系统要干什么回到最简单的代码:data = { t
2023-06-30

vue2基本响应式实现方式之让数组也变成响应式

这篇文章主要介绍了vue2基本响应式实现方式之让数组也变成响应式问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-17

Vue3响应式系统怎么实现computed

首先,我们简单回顾一下:响应式系统的核心就是一个WeakMap---Map---Set的数据结构。WeakMap的key是原对象,value是响应式的Map。这样当对象销毁的时候,对应的Map也会销毁。Map的key就是对象的每个属性,value是依赖这个对象属性的effect函数的集合Set。然后用Proxy代理对象的get方法,收集依赖该对象属性的effect函数到对应key的Set中。还要代理对象的set方法,修改对象属性的时候调用所有该key的effect函数。上篇文章我们按照这样的思路
2023-05-15

mybatisplus之怎么实现in嵌套sql

这篇文章主要讲解了“mybatisplus之怎么实现in嵌套sql”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mybatisplus之怎么实现in嵌套sql”吧!mybatis-plus实
2023-07-05

使用Java怎么实现响应式系统

使用Java怎么实现响应式系统?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。初识响应式系统ReactiveX的本质就是Observer+Iterator+函数编程+异步。是一个
2023-06-15

怎么应用Fedora7嵌入式系统

本篇内容主要讲解“怎么应用Fedora7嵌入式系统”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么应用Fedora7嵌入式系统”吧!编译安装miniGUI 1.6.2首先要做好准备工作,下载一
2023-06-16

Vue3响应式系统如何实现computed

这篇“Vue3响应式系统如何实现computed”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue3响应式系统如何实现co
2023-07-06

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录