前端开发攻略---从源码角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章让你彻底弄懂响应式原理。

这篇具有很好参考价值的文章主要介绍了前端开发攻略---从源码角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章让你彻底弄懂响应式原理。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、思考

Vue的响应式到底要干什么?

  • 无非就是要知道当你读取对象的时候,要知道它读了。要做一些别的事情
  • 无非就是要知道当你修改对象的时候,要知道它改了。要做一些别的事情
  • 所以要想一个办法,把读取和修改的动作变成一个函数,读取和修改的时候分别调用对应的函数
  • 在ES6之,只能通过Object.defineproperty 给它变成一个get和set函数。当读取这个属性的时候运行get,修改这个属性的时候运行set

  • 在ES6之后,就能通过Porxy去代理整个对象

2、Vue2的做法 

针对某个对象中某个属性的做法

通过Object.defineProperty去针对某个对象的属性去进行监听                           

const obj = {
  a: 1,
  b: 2,
  c: {
    d: 3,
    e: 4,
  },
}

// 保存初始值
let v = obj.a

Object.defineProperty(obj, 'a', {
  get() {
    console.log('a', '读取')
    return v
  },
  set(val) {
    // 当原来的值与重新赋值的值不一样的时候才进行修改
    if (val !== v) {
      console.log('a', '更改了')
      v = val
    }
  },
})

当我们去读取 obj.a 这个属性的时候 get 函数 就会调用。

当我们去修改 obj.a 这个属性的时候 set 函数 就会调用。

前端开发攻略---从源码角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章让你彻底弄懂响应式原理。,前端开发攻略,前端,javascript,vue.js

针对某个对象中多个属性的做法

Vue2的源码中,有一个函数叫做 observe(观察器)。在这个函数中,去深度遍历对象中的每一个属性,给每一个属性添加 Object.defineProperty,这样就能对对象中的每一个属性叫做监听。这个过程就叫做 观察

const obj = {
  a: 1,
  b: 2,
  c: {
    d: 3,
    e: 4,
  },
}
// 辅助函数 判断这个值是不是一个对象
function _isObject(v) {
  return typeof v === 'object' && v !== null
}
function observe(obj) {
  for (const k in obj) {
    let v = obj[k]
    // 如果这一个属性仍然是一个对象的话,就需要深度遍历
    if (_isObject(v)) {
      observe(v)
    }
    Object.defineProperty(obj, k, {
      get() {
        console.log(k, '读取了')
        return v
      },
      set(val) {
        // 当原来的值与重新赋值的值不一样的时候才进行修改
        if (val !== v) {
          console.log(k, '更改了')
          v = val
        }
      },
    })
  }
}
observe(obj)

当我们去读取对象中的某个属性的时候 get 函数 就会调用。

当我们去修改对象中的某个属性的时候 set 函数 就会调用。

前端开发攻略---从源码角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章让你彻底弄懂响应式原理。,前端开发攻略,前端,javascript,vue.js

打印内容解释:

  • obj.a  =  3   更改
  • obj.c.d  = 4  先读取 obj.c 的值,再更改 obj.c.d 的值
  • obj.c.e   先读取 obj.c 的值,再读取 obj.c.e 的值

总结

  1. 在Vue2里面观察的方式就是 深度遍历每一个属性 把每一个属性的读取和赋值变成函数get和set。
  2. 在这种做法下有一个天生的缺陷,由于它是针对每个属性的监听,所以就必须要进行深度的遍历,这样会有效率损失。 
  3. 由于在 observe(obj) 观察这个步骤里边完成了深度遍历,也就是说在这个时间点里边,这些属性被我们监听到了都被改成get和set了
  4. 但是这一步一旦做完了之后。再去新增的话它就不知道了。比如 obj.qwertr = 3 对于这个属性而言,它就是没有监听的,因为监听的步骤已经结束了

  5. 这就是为什么Vue2它无法监听属性的新增,当然也包括属性的删除。它也收不到通知。因为在 Object.defineProperty 既不会运行get也不会运行set

3、Vue3的做法

其实核心道理都是一样的。无论是Vue2还是Vue3,都必须要把读取和赋值变成函数。只不过Vue3变成函数的方式不一样。在Vue3里面不会去对对象的每一个属性进行监听了,而是直接监听整个对象。将来不管是在这个对象中添加还是删除属性都不怕了。因为监听的是整个对象,这要动了这个对象就能收到通知。

做法

Vue3使用的是Proxy

const obj = {
  a: 1,
  b: 2,
  c: {
    d: 3,
    e: 4,
  },
}

const proxy = new Proxy(obj, {
  // 读这个对象的属性的时候收到通知
  get(target, k) {
    // target就是obj,k是属性名
    let v = target[k]
    console.log(k, '读取')
    return v
  },
  // 修改这个对象的属性的时候收到通知
  set(target, k, val) {
    // target就是obj,k是属性名,val是新值
    if (target[k] !== val) {
      target[k] = val
      console.log(k, '更改')
      return target[k]
    }
  },
  // 删除对象的属性的时候收到通知
  deleteProperty(target, k, val) {
    console.log(k, '删除')
    return target[k]
  },
})

会产生一个代理对象propx,将来去读属性也好,重新给属性赋值也好都是通过这个代理对象去做的。

前端开发攻略---从源码角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章让你彻底弄懂响应式原理。,前端开发攻略,前端,javascript,vue.js

总结

  1. Proxy 对象可以直接代理整个对象,而不需要遍历对象属性进行劫持,这样可以减少运行时的性能开销。在 Vue 2 中,由于每个属性都需要单独设置 get 和 set,对于大量的属性或嵌套属性,这种劫持可能会导致性能下降。
  2. 另外,使用 Proxy 的方式更符合现代 JavaScript 的发展趋势,更好地利用了 JavaScript 引擎的优化。

4、总结

综上所述,Vue 3 中使用 Proxy 对象代替了 Vue 2 中的 Object.defineProperty,带来了更强大、更灵活和更高效的属性拦截和代理功能,同时也提升了开发体验和调试效率。这些改进使得 Vue 3 在处理 Props 的方式更加现代化和优雅,提升了整体的性能和可维护性。文章来源地址https://www.toymoban.com/news/detail-854516.html

到了这里,关于前端开发攻略---从源码角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章让你彻底弄懂响应式原理。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【前端开发工具】VUE3 devtools安装

    尤雨溪在2020年9月19日晚正式发布vue3.0 one piece。此版本相较于vue2版本,更快、更小、更易维护、更易于原生、让开发者更轻松;所以学习vue3,对于一个前端开发者来说是一个刻不容缓的学习趋势。 学习vue3自然也离不开debug啦~~ Vue官方发布了调试工具Vue-Devtools。 VUE3的Vue-Devt

    2024年02月05日
    浏览(35)
  • 从Vue2到Vue3, 一键升级前端开发技能

    本文的目的,是为了让已经有 Vue2 开发经验的   人   ,快速掌握 Vue3 的写法。 因此,   本篇假定你已经掌握 Vue 的核心内容   ,只为你介绍编写 Vue3 代码,需要了解的内容。 首先,Vue3 新增了一个叫做组合式 api 的东西,英文名叫 Composition API 。因此 Vue3 的  script  现在支

    2024年02月08日
    浏览(60)
  • Vue3前端开发,computed计算属性的基础练习

    Vue3前端开发,computed计算属性的基础练习! 在新版里面,和传统的vue2一样,计算属性,都是对一些数据运算进行了封装操作。返回结果是一个实时监控的效果。区别在于,写法不同。效果是一样。 下面给大家展示一个简单的案例。 如图,自定义一个组件,ComputedDemo.vue。里

    2024年01月18日
    浏览(34)
  • Vue3前端开发,watch数据侦听器的立即执行

    Vue3前端开发,watch数据侦听器的立即执行!实际上,我们可以通过回调函数的后面,再追加一个对象,来设置这个参数,immediate:true.来实现一种立即执行的效果。在页面记载完成后,马上就会执行一次watch. 如上所示,我们在回调函数的后面,追加了一个参数,是一个对象类型

    2024年01月18日
    浏览(32)
  • Vue3前端开发,父组件给子组件传递数据练习

    Vue3前端开发,父组件给子组件传递数据练习!还是借用刚刚的组件模板,来开展父传子的练习。 依旧是需要借助官方提供的宏函数来接收数据。defineProps. 这个是父组件里面的内容。我们自定义了2个变量,一个是车厘子单价。一个是纯文本。 一个数字类型,一个文本类型。都

    2024年01月22日
    浏览(29)
  • vue3前端开发,自学一下reactive,ref的差异是什么。

    vue3前端开发,自学,学习一下,reactive和ref的差别。以及基础用法。 前言,这2个东西,都能对外输出动态的数据对象。但是,有点区别,是,reactive只支持输入一个对象作为参数,ref则还可以支持简单的数据信息作为参数。待会有案例代码展示。 下面看看代码内容。第一个

    2024年01月18日
    浏览(36)
  • vue3 + Tailwind Css + Vite 搭建快速开发前端样式环境

    一个功能类优先的 CSS 框架,用于快速构建定制的用户界面。这是来自 TailwindCss 官方定义。 中文网站 Tailwindcss 基于原子化理念,将样式重复性代码降到最小,原本开发最大限度基于类名的声明块不重复,现在Tailwindcss基于单独一句声明不重复。 活跃度 github starts 数量达到

    2024年02月04日
    浏览(40)
  • Vue3前端开发,watch侦听器的深度监听和精确监听

    Vue3前端开发,watch侦听器的深度监听和精确监听!今天和大家分享的内容是,关于watch的深度侦听和精确监听。 首先看一下,第一个案例,练习的是,深度监听的效果。默认是浅的侦听,是不会触发回调函数的。 如图,当我们点击按钮,修改num值的时候,触发了回调函数,在

    2024年01月23日
    浏览(28)
  • 从壹开始前后端开发【.Net6+Vue3】(二)前端创建

    工作后,学习的脚步一直停停走走,希望可以以此项目为基础,可以不断的迫使自己不断的学习以及成长 将以Girvs框架为基础,从壹开始二次开发一个前后端管理框架 在这过程中一步步去学习使用到的技术点,也同时会将在此过程中遇到的问题进行分享 项目地址 上文介绍到

    2024年02月10日
    浏览(28)
  • 【Spring源码分析】从源码角度去熟悉依赖注入(二)

    阅读此需阅读下面这些博客先 【Spring源码分析】Bean的元数据和一些Spring的工具 【Spring源码分析】BeanFactory系列接口解读 【Spring源码分析】执行流程之非懒加载单例Bean的实例化逻辑 【Spring源码分析】从源码角度去熟悉依赖注入(一) 上篇这里简单提一下哈,怕有些没看的,

    2024年01月25日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包