Vue2和Vue3响应式原理实现的核心

这篇具有很好参考价值的文章主要介绍了Vue2和Vue3响应式原理实现的核心。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Vue简介

Vue.js 是一个开源的渐进式 JavaScript 前端框架,主要用于构建用户界面和单页应用程序(SPA)。Vue.js 可以轻松地与其他库或现有项目集成使用,并被认为是开发响应式数据驱动的现代 Web 应用的一种有效方式。

Vue.js 的核心特点:

  1. 响应式数据绑定:Vue.js 可以通过对数据进行双向绑定来响应用户输入和页面变化。
  2. 组件化:Vue.js 使得开发者可以将单个组件变成一个独立的模块,组件性能优良且可以重复利用。
  3. 基于模板的语法:Vue.js 提供了一套模板语法,使得开发者可以简单地编写 HTML 模板,并将其与 Vue.js 组件绑定。

Vue2的响应式原理

Vue2 的响应式原理建立在 ES5 的 Object.defineProperty() 上,该方法可以定义对象的属性,并对其进行劫持,当属性值发生变化时,Vue 可以检测到该变化并重新渲染相应的页面内容。

具体实现原理如下:

  1. 在 Vue 的初始化阶段,Vue 会对传入的 data 对象进行递归劫持,将 data 对象的所有属性都转换成 getter/setter 形式。
  2. 当页面中使用数据时,Vue 会通过访问属性的方式触发 getter 函数,从而将当前的 Watcher (观察者)对象加入到当前属性的依赖中。
  3. 当数据发生变化时,Vue 会通过监听器检测到变化,并触发对应属性的 setter 函数,从而通知该属性下所有的依赖 Watcher 更新;
  4. Watcher 对象被通知后,会向对应的组件发送消息通知需要重新渲染视图,从而实现整个页面的更新。

需要注意,Vue2 只能监听对象属性的变化,并不能监听到添加/删除对象属性、数组方法的变化,因此我们可以使用 Vue.set() 或者 Vue.delete() 方法来更新对象属性,但是只能使用原生 JavaScript 数组的 push()pop()splice()shift()unshift() 方法等来操作数组。

Vue2数据劫持的示例代码如下:

const data = { msg: 'Hello Vue' }

Object.defineProperty(data, 'msg', {
  get() {
    console.log('get');
    return val;
  },
  set(newValue) {
    console.log('set', newValue);
    val = newValue;
  }
})

Object.defineProperty()详解

Object.defineProperty() 是在 ES5 中新增的一个方法,用于为对象定义新的属性或修改对象的属性,其语法如下:

Object.defineProperty(obj, prop, descriptor)

其中的参数含义:

  • obj:要定义属性的对象。
  • prop:要定义或修改的属性的名称。
  • descriptor:需要定义或修改的属性描述符对象。

属性描述符对象中包含以下可选属性:

  • value:属性的值,默认为 undefined。
  • writable:如果为 true,则该属性的值可以被赋值运算符改变,默认为 false。
  • enumerable:如果为 true,则该属性可以在枚举对象属性时被枚举,默认为 false。
  • configurable:如果为 true,则可以使用 Object.defineProperty() 方法修改该属性的描述符,默认为 false。
  • get:属性读取方法。
  • set:属性赋值方法。

Object.defineProperty()的缺点

  • 无法监听数组的变化
    Vue2 把会修改原来数组的方法定义为变异方法。
    变异方法例如 push、pop、shift、unshift、splice、sort、reverse等,是无法触发 set 的。
    非变异方法,例如 filter,concat,slice 等,它们都不会修改原始数组,而会返回一个新的数组。
    Vue2 的做法是把这些变异方法重写来实现监听数组变化。
  • 必须遍历对象的每个属性
    使用 Object.defineProperty 多数情况下要配合 Object.keys 和遍历,于是就多了一层嵌套。
    并且由于遍历的原因,假如对象上的某个属性并不需要“劫持”,但此时依然会对其添加“劫持”。
  • 必须深层遍历嵌套的对象
    当一个对象为深层嵌套的时候,必须进行逐层遍历,直到把每个对象的每个属性都调用 Object.defineProperty() 为止。

Vue3的响应式原理

Vue3 的响应式原理主要使用了 ES6 的 Proxy 代替了 Vue2 中的 Object.defineProperty(),从而实现了更加高效和强大的数据劫持和响应式。

Proxy 对象可以通过对访问和修改数据的拦截来实现数据劫持。而 Reflect 对象则提供了更加灵活和易用的数据操作方法,比如可以使用 Reflect.has() 来检查对象是否有某个属性,使用 Reflect.defineProperty() 来代替 Object.defineProperty()。

具体实现原理如下:

  1. 在 Vue3 的初始化阶段,Vue3 会对传入的 data 对象通过使用 Proxy 对象进行代理,即使用 new Proxy(target, handler),其中 target 是被代理的对象,handler 是一个对象,用来定义代理 target 中的操作。

  2. 当页面中使用数据时,Vue3 会触发 get 操作,代理对象 handler.get() 会被调用,进而让 handler 捕获该操作,并将当前的 Watcher (观察者)对象加入到当前属性的依赖中。

  3. 当数据发生变化时,Vue3 会通过监听器检测到变化,并触发对应数据的 set 操作,代理对象 handler.set() 会被调用,从而通知该属性下所有依赖的 ‘Watcher’ 对象更新;

  4. Watcher 对象被通知后,会向对应的组件发送消息通知需要重新渲染视图,从而实现整个页面的更新。

Vue3 中使用 Proxy 对象实现数据响应式的代码如下:

const data = { msg: 'Hello Vue' }

const reactiveData = new Proxy(data, {
  get(target, key) {
    console.log('get');
    return target[key];
  },
  set(target, key, value) {
    console.log('set');
    target[key] = value;
    return true;
  }
})

上述代码中,data 对象通过 Proxy 对象 reactiveData 进行代理,当访问 reactiveData 对象的属性时,Proxy 对象内部的 get() 函数被调用;当设置属性时,Proxy 对象内部的 set() 函数被调用。在 get() 和 set() 函数中,可以对属性的读取和赋值进行拦截,从而实现数据的响应式。

Proxy详解

Proxy 是在 ES6 中新增的一个对象,用于代理另一个对象并拦截该对象的读取、赋值、属性定义等一系列操作,其语法如下:

new Proxy(target, handler)

Proxy中的参数:

  • target:被代理的目标对象。
  • handler:一个对象,其属性是钩子函数(trap),用于拦截代理对象的操作。

handler 包含以下可选钩子函数(trap):文章来源地址https://www.toymoban.com/news/detail-476963.html

  • get(target, prop):用于拦截对象的读取操作。
  • set(target, prop, value):用于拦截对象的赋值操作。
  • has(target, prop):用于拦截 in 操作。
  • deleteProperty(target, prop):用于拦截 delete 操作。
  • apply(target, thisArg, args):用于拦截函数调用。
  • construct(target, args):用于拦截 new 操作。

Proxy的优点

  • Proxy可以直接监听对象而非属性;
  • Proxy可以直接监听数组的变化;
  • Proxy返回的是一个新对象,我们可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改;

到了这里,关于Vue2和Vue3响应式原理实现的核心的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Vue2向Vue3过度核心技术插槽

    1.作用 让组件内部的一些 结构 支持 自定义 2.需求 将需要多次显示的对话框,封装成一个组件 3.问题 组件的内容部分, 不希望写死 ,希望能使用的时候 自定义 。怎么办 4.插槽的基本语法 组件内需要定制的结构部分,改用****占位 使用组件时, ****标签内部, 传入结构替换slo

    2024年02月11日
    浏览(42)
  • Vue2向Vue3过度核心技术路由

    1.思考 单页面应用程序,之所以开发效率高,性能好,用户体验好 最大的原因就是: 页面按需更新 比如当点击【发现音乐】和【关注】时, 只是更新下面部分内容 ,对于头部是不更新的 要按需更新,首先就需要明确: 访问路径 和 组件 的对应关系! 访问路径 和 组件的对

    2024年02月11日
    浏览(52)
  • Vue2.0 的响应式原理 私

    使用的Object.defineProperty()重新定义对象,给data的每个属性都添加了getter和setter方法。这时候会为对象的每个属性创建一个Dep实例  (依赖)。Dep实例可以订阅和通知相关的Watcher实例。,  这一步叫  数据劫持  或者 依赖收集 在数据发生更新后调用 set 时会通知发布者 notify

    2024年02月11日
    浏览(38)
  • vue2响应式原理----发布订阅模式

    很多人感觉vue2的响应式其实用到了观察者+发布订阅。我们先来看一下简单的发布订阅的代码: 从上面中发现一个重要的点,发布者和订阅者是根据key值来区分的,然后通过消息中心来中转的,他们家是是实现不知道对方是谁。 而观察者模式中观察者是一开始就知道自己观察

    2024年04月14日
    浏览(41)
  • 从Vue2到Vue3【零】——Vue3简介及创建

    内容 链接 从Vue2到Vue3【零】 Vue3简介 从Vue2到Vue3【一】 Composition API(第一章) 从Vue2到Vue3【二】 Composition API(第二章) 从Vue2到Vue3【三】 Composition API(第三章) 从Vue2到Vue3【四】 Composition API(第四章) Vue.js作为一种流行的JavaScript框架已经被广泛应用于前端开发中。随着

    2024年02月16日
    浏览(42)
  • Vue2向Vue3过度Vuex核心概念mutations

    1.定义mutations 2.格式说明 mutations是一个对象,对象中存放修改state的方法 3.组件中提交 mutations 4.练习 1.在mutations中定义个点击按钮进行 +5 的方法 2.在mutations中定义个点击按钮进行 改变title 的方法 3.在组件中调用mutations修改state中的值 5.总结 通过mutations修改state的步骤 1.定义

    2024年02月11日
    浏览(44)
  • 202 vue2的响应式原理 通俗易懂!

    Object.defineProperty + 依赖追踪 。 在Vue实例化过程中,会 递归 地将 每个数据对象 的 属性 转换为 getter/setter ,并维护一个 依赖收集器(Dep) 。 每个属性 都有一个关联的 watcher ,当 数据发生 变化时 , watcher 会 被通知 并 更新视图 。 Vue 2.x 实现响应式数据: vue实例化 时,会

    2024年02月06日
    浏览(42)
  • Vue | (一)Vue核心(上) | 尚硅谷Vue2.0+Vue3.0全套教程

    学习链接:尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通,本文对应p1-p25,博客参考尚硅谷公开笔记,补充记录实操。 英文官网 中文官网 关于官网(与视频p3已略有出入):文档指南,API查字典,互动指南,示例… Vue开发者工具安装 vscode插件安装,提效 想让Vue工作,就必

    2024年02月20日
    浏览(52)
  • Vue | (一)Vue核心(下) | 尚硅谷Vue2.0+Vue3.0全套教程

    学习链接:尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通,本文对应p26-p52,博客参考尚硅谷公开笔记,补充记录实操。 在应用界面中, 某个(些)元素的样式是变化的。 class/style 绑定就是专门用来实现动态样式效果的技术。 class样式 写法: class=\\\"xxx\\\" ,xxx可以是字符串、对象、数

    2024年02月19日
    浏览(50)
  • Vue2向Vue3过度核心技术工程化开发和脚手架

    1.1 开发Vue的两种方式 核心包传统开发模式:基于html / css / js 文件,直接引入核心包,开发 Vue。 工程化开发模式:基于构建工具(例如:webpack)的环境中开发Vue。 工程化开发模式优点: 提高编码效率,比如使用JS新语法、Less/Sass、Typescript等通过webpack都可以编译成浏览器识

    2024年02月11日
    浏览(55)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包