返回顶部
首页 > 资讯 > 精选 >Vue2响应式系统之set和delete怎么用
  • 956
分享到

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

2023-06-30 01:06:34 956人浏览 八月长安
摘要

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

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

1、数组

import { observe } from "./Reactive";import Watcher from "./watcher";const data = {    list: [1, 2],};observe(data);const updateComponent = () => {    console.log(data.list);};new Watcher(updateComponent);list[0] = 3;

list[0]会触发 的重新执行吗?updateComponent

可以先思考一下。

答案是否定的,数组我们只能通过重写的 、 等方法去触发更新,详见pushspliceVue2响应式系统之数组 。

如果我们想要替换数组某个元素的话可以转一下弯,通过 去实现。splice

import { observe } from "./reactive";import Watcher from "./watcher";const data = {    list: [1, 2],};observe(data);const updateComponent = () => {    console.log(data.list);};new Watcher(updateComponent);// list[0] = 3;data.list.splice(0, 1, 3);

每次这样写太麻烦了,我们可以提供一个 方法供用户使用。set

export function set(target, key, val) {    if (Array.isArray(target)) {        target.length = Math.max(target.length, key);        target.splice(key, 1, val);        return val;    }    // targe 是对象的情况    // ...}

然后我们直接使用 方法就可以了。set

import { observe, set } from "./reactive";import Watcher from "./watcher";const data = {    list: [1, 2],};observe(data);const updateComponent = () => {    console.log(data.list);};new Watcher(updateComponent);// list[0] = 3;// data.list.splice(0, 1, 3);set(data.list, 0, 3);

2、数组 del

同数组 ,我们顺便提供一个 的方法,支持数组响应式的删除某个元素。setdel

export function del(target, key) {    if (Array.isArray(target) && isValidArrayIndex(key)) {        target.splice(key, 1);        return;    }    // targe 是对象的情况    // ...}

3、对象 set

import { observe, set, del } from "./reactive";import Watcher from "./watcher";const data = {    obj: {        a: 1,        b: 2,    },};observe(data);const updateComponent = () => {    const c = data.obj.c ? data.obj.c : 0;    console.log(data.obj.a + data.obj.b + c);};new Watcher(updateComponent);data.obj.c = 3;

updateComponent 方法中虽然使用了 的 属性,但是在调用 之前, 中并没有 属性,所以 属性不是响应式的。objcobservedata.objcc

当我们修改 的值的时候,并不会触发 的执行。data.obj.cupdateComponent

如果想要变成响应式的话,一种方法就是在最开始就定义 属性。c

const data = {    obj: {        a: 1,        b: 2,        c: null,    },};observe(data);const updateComponent = () => {    const c = data.obj.c ? data.obj.c : 0;    console.log(data.obj.a + data.obj.b + c);};new Watcher(updateComponent);data.obj.c = 3;

另一种方法就是通过 去设置新的属性了,在 中我们可以将新添加的属性设置为响应式的。setset

export function set(target, key, val) {    if (Array.isArray(target)) {        target.length = Math.max(target.length, key);        target.splice(key, 1, val);        return val;    }    // targe 是对象的情况    // key 在 target 中已经存在    if (key in target && !(key in Object.prototype)) {        target[key] = val;        return val;    }    const ob = target.__ob__;    // target 不是响应式数据    if (!ob) {        target[key] = val;        return val;    }  // 将当前 key 变为响应式的    defineReactive(target, key, val);    return val;}

回到我们之前的程序:

import { observe, set, del } from "./reactive";import Watcher from "./watcher";const data = {    obj: {        a: 1,        b: 2,    },};observe(data);const updateComponent = () => {    const c = data.obj.c ? data.obj.c : 0;    console.log(data.obj.a + data.obj.b + c);};const ob = new Watcher(updateComponent);set(data.obj, "c", 3);

虽然通过 增加了属性,但是此时 并不会重新触发,原因的话我们看下依赖图。setWatcher

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

虽然属性 拥有了 对象,但由于没有调用过依赖属性 的 ,所以它并没有收集到依赖。cDepcWatcher

当然我们可以 完手动调用一次相应的 。setWatcher

const data = {    obj: {        a: 1,        b: 2,    },};observe(data);const updateComponent = () => {    const c = data.obj.c ? data.obj.c : 0;    console.log(data.obj.a + data.obj.b + c);};const ob = new Watcher(updateComponent);set(data.obj, "c", 3);ob.update(); // 手动调用 Watcherdata.obj.c = 4;

这样的话,当执行 的时候就会触发 的执行了。data.obj.c = 4Watcher

那么我们能将触发相应的 的逻辑放到 函数中吗?Watcherset

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

可以看到 里也有个 ,这个其实当时是为数组准备的,参考 objDepVue2响应式系统之数组,但 的 什么都没收集。objdep

我们修改一下代码让它也收集一下:

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();                if (childOb) {                                  childOb.dep.depend();                                      if (Array.isArray(value)) {                       // childOb.dep.depend(); //原来的位置                        dependArray(value);                    }                }            }            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();        },    });}function dependArray(value) {    for (let e, i = 0, l = value.length; i < l; i++) {        e = value[i];              e && e.__ob__ && e.__ob__.dep.depend();              if (Array.isArray(e)) {           //  e && e.__ob__ && e.__ob__.dep.depend(); // 原位置            dependArray(e);        }    }}

因为读取 属性,一定先会读取 属性,即 。 也同理。aobjdata.obj.ab

所以通过上边的修改, 的 会收集到它的所有属性的依赖,也就是这里的 、 的依赖,但因为 和 的依赖是相同的,所以收集到一个依赖。objdepabab

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

但其实我们并不知道 被哪些 依赖,我们只知道和 同属于一个对象的 和 被哪些 依赖,但大概率 也会被其中的 依赖。cWatchercabWatchercWatcher

所以我们可以在 中手动执行一下 的 ,依赖 的 大概率会被执行,相应的 也会成功收集到依赖。setobjDepcWatcherc

export function set(target, key, val) {    if (Array.isArray(target)) {        target.length = Math.max(target.length, key);        target.splice(key, 1, val);        return val;    }    // targe 是对象的情况    // key 在 target 中已经存在    if (key in target && !(key in Object.prototype)) {        target[key] = val;        return val;    }    const ob = target.__ob__;    // target 不是响应式数据    if (!ob) {        target[key] = val;        return val;    }    defineReactive(target, key, val);       ob.dep.notify()         return val;}

回到最开始的代码:

const data = {    obj: {        a: 1,        b: 2,    },};observe(data);const updateComponent = () => {    const c = data.obj.c ? data.obj.c : 0;    console.log(data.obj.a + data.obj.b + c);};const ob = new Watcher(updateComponent);set(data.obj, "c", 3);

执行完后 除了变为响应式的,也成功触发了 执行,并且收集到了 。cWatcherWatcher

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

此时如果修改 的值,也会成功触发 的执行了。cWatcher

4、对象 del

有了上边的了解,删除就很好解决了。

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

如果要删除 属性,删除后执行下它相应的 就可以。但 的 是存在闭包中的,我们并不能拿到。aDepaDep

退而求其次,我们可以去执行 属性所在的对象 的 就可以了。aobjDep

export function del(target, key) {    if (Array.isArray(target)) {        target.splice(key, 1);        return;    }    // targe 是对象的情况    const ob = target.__ob__;    if (!hasOwn(target, key)) {        return;    }    delete target[key];    if (!ob) {        return;    }    ob.dep.notify();}

以上就是“Vue2响应式系统之set和delete怎么用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: Vue2响应式系统之set和delete怎么用

本文链接: https://lsjlt.com/news/326950.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Vue2响应式系统之set和delete
    目录1、数组集2、数组 del3、对象 set4、对象 del5、总结1、数组集 import { observe } from "./reactive"; import Watch...
    99+
    2024-04-02
  • Vue2响应式系统之set和delete怎么用
    今天小编给大家分享一下Vue2响应式系统之set和delete怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。...
    99+
    2023-06-30
  • Vue2 响应式系统之深度响应
    目录1、场景2、方案3、场景24、总结1、场景 import { observe } from "./reactive"; import Watcher from "./watche...
    99+
    2024-04-02
  • Vue2响应式系统之深度响应怎么实现
    本文小编为大家详细介绍“Vue2响应式系统之深度响应怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue2响应式系统之深度响应怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1、场景import&...
    99+
    2023-06-30
  • Vue2响应式系统之嵌套
    目录1、场景2、执行过程3、修复4、测试5、总结1、场景 在 开发中肯定存在组件嵌套组件的情况,类似于下边的样子。Vue <!-- parent-component ...
    99+
    2024-04-02
  • Vue2 响应式系统之数组
    目录1、场景2、场景 23、方案3、收集依赖代码实现4、通知依赖代码实现5、测试6、总结本文接Vue2响应式系统 、Vue2 响应式系统之分支切换  ,...
    99+
    2024-04-02
  • Vue2响应式系统之嵌套怎么实现
    这篇“Vue2响应式系统之嵌套怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue2响应式系统之嵌套怎么实现”文章吧...
    99+
    2023-06-30
  • Vue2响应式系统有什么用
    这篇文章主要讲解了“Vue2响应式系统有什么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue2响应式系统有什么用”吧!一、响应式系统要干什么回到最简单的代码:data =&n...
    99+
    2023-06-30
  • Vue2响应式系统之怎么让数组生效
    这篇文章主要介绍了Vue2响应式系统之怎么让数组生效的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue2响应式系统之怎么让数组生效文章都会有所收获,下面我们一起来看看吧。1、场景import {&n...
    99+
    2023-06-30
  • Vue2 响应式系统之异步队列
    目录场景解决方案代码实现执行结果总结试想一下如果这里的 console.log 是渲染页面,那改变一次值就刷新一下页面,会造成严重的性能问题,页面也会不停的改变。 场景 import...
    99+
    2024-04-02
  • Vue2 响应式系统之分支切换
    目录场景observer(data)new Watcher(updateComponent)data.ok = falsedata.text = "hello, ...
    99+
    2024-04-02
  • Vue2响应式系统介绍
    目录一、响应式系统要干什么二、响应式数据三、保存当前正在执行的函数四、响应式数据五、Observer 对象六、测试七、总结前言: 目前工作中大概有 的需求是在用 ...
    99+
    2024-04-02
  • Vue2响应式系统之异步队列怎么实现
    这篇“Vue2响应式系统之异步队列怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue2响应式系统之异步队列怎么实现...
    99+
    2023-06-30
  • Vue2响应式系统之分支切换怎么实现
    本篇内容介绍了“Vue2响应式系统之分支切换怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!场景我们考虑一下下边的代码会输出什么。im...
    99+
    2023-06-30
  • 使用Java怎么实现响应式系统
    使用Java怎么实现响应式系统?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。初识响应式系统ReactiveX的本质就是Observer+Iterator+函数编程+异步。是一个...
    99+
    2023-06-15
  • 怎么手写Vue3响应式系统
    这篇文章主要介绍了怎么手写Vue3响应式系统的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么手写Vue3响应式系统文章都会有所收获,下面我们一起来看看吧。响应式首先,什么是响应式呢?响应式就是被观察的数据变化...
    99+
    2023-07-02
  • Vue3响应式系统怎么实现computed
    首先,我们简单回顾一下:响应式系统的核心就是一个 WeakMap --- Map --- Set 的数据结构。WeakMap 的 key 是原对象,value 是响应式的 Map。这样当对象销毁的时候,对应的 Map 也会销毁。Map 的 ...
    99+
    2023-05-15
    Vue3 computed
  • 什么是Vue响应式系统
    什么是Vue响应式系统,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。响应式系统(Reactivity systems)是现代前端框架的关键部分...
    99+
    2024-04-02
  • 怎么理解Vue 3.0的响应式系统
    这篇文章主要介绍“怎么理解Vue 3.0的响应式系统”,在日常操作中,相信很多人在怎么理解Vue 3.0的响应式系统问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解Vu...
    99+
    2024-04-02
  • 前端响应式布局与Bootstrap栅格系统怎么应用
    这篇“前端响应式布局与Bootstrap栅格系统怎么应用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“前端响应式布局与Boo...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作