vue响应式Object代理对象的修改和删除属性

 更新时间:2022年08月02日 10:37:30   作者:冒菜师  
这篇文章主要为大家介绍了vue响应式Object代理对象的修改和删除属性示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

上一篇文章我们学习了如何代理对象的读取,下面我们学习如何代理对象的修改和删除属性。

set

set就是修改代理的属性,按照我们之前写的reactive,它大概是这样的

const ITERATE_KEY=symbol()
const p = new Proxy(obj,{
 set(target,key,newVal,receiver){
        const res = Reflect.set(target,key,newVal,receiver)
        trigger(target,key)
        return res
  }
}

细心的朋友应该发现了,我专门把ITERATE_KEY也加进来了,但是在set中并没有使用,难道是多余的?

这里其实有一个小坑,就是如果曾经对对象使用过for ... in,这里会出现2种情况:

  • 如果我们新增了一个属性,那么我们是不是应该重新运行一次for ... in的副作用函数。
  • 如果我们只是修改某个属性而不是新增,那么我们就不应该重新运行for ... in的副作用函数. 所以我们需要判断一下它是新增还是修改
//定义常量,在ts中可以使用枚举
const TriggerType = {
    SET:'SET',
    ADD:'ADD'
}
const p = new Proxy(obj,{
 set(target,key,newVal,receiver){
         //判断新增还是修改
         const type = Object.prototype.hasOwnProperty.call(target,key) 
         ? TriggerType.SET
         : TriggerType.ADD
        const res = Reflect.set(target,key,newVal,receiver)
        trigger(target,key,type)
        return res
  }
}

同时,对应trigger函数中,我们也需要根据type读取ITERATE_KEY对应的副作用函数.

const trigger = (target,key,type)=>{
    const depsMap = targetMap.get(target)
    if(!depsMap){
        return 
    }
    const effects = depsMap.get(key)
    // 再次去重
    const needToRun = new Set()
    if(effects){
        effects.forEach(e=> e!==activeEffect
            ? needToRun.add(e)
            : ''
        )
    }
    if(type === TriggerType.ADD){
        const otherEffects = depsMap.get(ITERATE_KEY)
        if(otherEffects){
            otherEffects.forEach(e=> e!==activeEffect
                ? needToRun.add(e)
                : ''
            )
        }
    }
    if(needToRun.length){
        needToRun.forEach(fn=> fn?.options?.scheduler ? fn.options.scheduler(fn) : fun())
    }
}

这样,我们只在新增的时候才会调用for ... in的副作用函数。

delete

删除的时候,之前貌似没写过。这里需要注意2个点。

  • 保证属性删除之后才运行副作用,这里从逻辑上讲我们最好先验证这个属性是否存在,避免报错。
  • 删除时也要运行for ... in的副作用函数

因此我们这样定义,给TriggerType新增一个类型DEL

const TriggerType = {
    SET:'SET',
    ADD:'ADD',
    DEL:'DELETE'
}

然后,我们开始拦截删除属性的操作,查一下之前的Proxy内部方法的表,我们可以得知,删除属性对应着deleteProperty方法。

const p = new Proxy(obj,{
 deleteProperty(target,key){
         //判断属性存在,你总不能删除一个不存在的属性吧
        const hadKey = Object.prototype.hasOwnProperty.call(target,key)  
        const res = Reflect.deleteProperty(target,key)
        if(res && hadKey){
            trigger(target,key,TriggerType.DEL)
        }
        return res
  }
}

对应trigger函数中,我们小修改一下,其他逻辑不变

// 删除这句
- if(type === TriggerType.ADD){
// 改为
+ if([TriggerType.ADD,TriggerType.DEL].includes(type)){

这样就可以实现响应式对象的删除属性。

其实原文中并没有使用Array.includes,但我觉得其实我们应该使用最新的语法,现在浏览器环境对这些新语法支持度已经很好了(如果你要兼容IE当我没说)。

这一篇就完结了,总结一下就是如何对对象的读取属性、修改属性、删除属性进行代理,大概了解vue3中对于对象的处理。

但是这里还没有结束,后续会讲一些边际条件,以及如何合理的响应数据变化和操作,合理也就是优化,尽可能的减少多余的响应。

更多关于vue响应式Object修改删除的资料请关注脚本之家其它相关文章!

相关文章

  • vue 框架下自定义滚动条(easyscroll)实现方法

    vue 框架下自定义滚动条(easyscroll)实现方法

    这篇文章主要介绍了vue 框架下自定义滚动条(easyscroll)实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • 使用vue实现通过变量动态拼接url

    使用vue实现通过变量动态拼接url

    这篇文章主要介绍了使用vue实现通过变量动态拼接url,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • vue 2.0项目中如何引入element-ui详解

    vue 2.0项目中如何引入element-ui详解

    element-ui是一个比较完善的UI库,但是使用它需要有一点vue的基础,下面这篇文章主要给大家介绍了关于在vue 2.0项目中如何引入element-ui的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • 详解Vue中$refs和$nextTick的使用方法

    详解Vue中$refs和$nextTick的使用方法

    这篇文章主要为大家介绍了Vue中$refs和$nextTick的使用方法,文中的示例代码讲解详细,对我们学习Vue有一定帮助,需要的可以参考一下
    2022-03-03
  • Vue项目中接口调用的详细讲解

    Vue项目中接口调用的详细讲解

    应公司需求,接口需要对接vue,记录一下碰到的问题,下面这篇文章主要给大家介绍了关于Vue项目中接口调用的详细讲解,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • vue中then后的返回值解析

    vue中then后的返回值解析

    这篇文章主要介绍了vue中then后的返回值解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • 前端vue面试总问watch和computed区别及建议总结

    前端vue面试总问watch和computed区别及建议总结

    在现代前端的面试中,vue和react是面试过程中基本必问的技术栈,其中Vue响应式话题,watch和computed是面试官非常喜欢聊的主题,虽然watch和computed它们都用于监听数据的变化,但它们在实现原理、使用场景和行为上有着显著的区别,本文将深入探讨,并提供一些面试过程中的建议
    2023-10-10
  • vue实战中的一些实用小魔法汇总

    vue实战中的一些实用小魔法汇总

    这篇文章主要给大家介绍了关于vue实战中一些实用小魔法的相关资料,这些技巧和窍门,可以帮助你成为更好的Vue开发人员,需要的朋友可以参考下
    2021-06-06
  • vue中生成条形码(jsbarcode)和二维码(qrcodejs2)的简单示例

    vue中生成条形码(jsbarcode)和二维码(qrcodejs2)的简单示例

    在vue项目中难免遇到有要生成条形码或者二维码的功能需求,下面这篇文章主要给大家介绍了关于vue中生成条形码(jsbarcode)和二维码(qrcodejs2)的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • 在Vue的mounted中仍然加载渲染不出echarts的方法问题

    在Vue的mounted中仍然加载渲染不出echarts的方法问题

    这篇文章主要介绍了在Vue的mounted中仍然加载渲染不出echarts的方法问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03

最新评论