Vue2和Vue3的区别

注:本文提到的Vue2版本是2.6.10;

双向绑定:监听对象属性变化的底层方法不同;

2中使用的是Object.defineProperty;3中则使用Proxy拦截;

Object.defineProperty

简单的写个方法,让监听对象属性的setter和getter

javascript 复制代码
function isObj(obj) {
      return typeof obj === 'object' && obj !== null;
    }

    function observe(obj) {
      if (isObj(obj)) {
        Object.keys(obj).forEach(property => {
          const v = obj[property]
          if (isObj(v)) {
            observe(v);
          } else {
            Object.defineProperty(obj, property, {
              get() {
                console.log('get');
                return v;
              },
              set(newValue) {
                if (newValue !== v) {
                  console.log('set');
                  v = newValue;
                }
              },
              enumerable: true,
              configurable: true,
            });
          }
        })
      }
    }

    const a = {
      a: 1,
      b: 'b',
      c: {
        ca: 1,
        cb: 'b',
      }
    }

    observe(a);

结果如上:可以监听到对应属性的setter和getter。

但是有个弊端,监听不到对象属性的删除和增加,对于数组方法也没办法监听。

  • 解决办法
    • 监听不到对象属性的删除和增加
typescript 复制代码
// 使用this.$set实现
this.task.status = 'pending'; // 视图无变化
this.$set(this.task, 'status', 'pending');  // 视图变化
this.$delete(this.task, 'status');  // 视图变化
  • 对于数组方法也没办法监听:

直接插入了一个新的原型对象,拦截数组原型上的方法

Proxy

typescript 复制代码
    const proxy = new Proxy(a, {
      get: function (obj, prop) {
        console.log('get');
        return obj[prop];
      },
      set: function (obj, prop, value) {
        if (obj[prop] !== value) {
          console.log('set');
          obj[prop] = value
        }
      },
    })


Proxy直接可以监听对象属性变化,不需要对属性进行深层遍历,还有一些其他的方法扩展,详见Proxy

总结:Object.defineProperty只能遍历对象属性进行劫持,Proxy直接劫持整个对象,3的性能好些,也好理解属性变化的监听,但是不支持低版本浏览器。但是Proxy拦截方法多(apply、ownKeys、deleteProperty等),2只能通过其他方法辅助实现,对应打包体积也会变大。

2更倾向于选项式配置,3是组合式API,方便维护代码。

相关推荐
A_nanda19 分钟前
Vue项目升级
前端·vue3·vue2
SuperEugene29 分钟前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
abigale031 小时前
【浏览器 API / 网络请求 / 文件处理】前端文件上传全流程:从基础上传到断点续传
前端·typescript·文件上传·vue cli
子兮曰1 小时前
Bun v1.3.11 官方更新全整理:新增功能、关键修复与升级验证
javascript·node.js·bun
Setsuna_F_Seiei1 小时前
AI 对话应用之页面滚动交互的实现
前端·javascript·ai编程
新缸中之脑2 小时前
追踪来自Agent的Web 流量
前端
wefly20172 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
英俊潇洒美少年3 小时前
vue如何实现react useDeferredvalue和useTransition的效果
前端·vue.js·react.js
英俊潇洒美少年3 小时前
ref 底层到底是怎么变成响应式的?
vue.js
kyriewen113 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript