当前位置: 首页 > news >正文

深入理解 Vue 3 的双向绑定原理与实现

Vue 3 双向绑定原理详解

一、什么是双向绑定?

双向绑定是 Vue.js 中一个重要的特性,它允许在模型数据和视图之间自动同步。当用户在视图中修改输入框的内容时,模型数据会自动更新;同样,当模型数据发生变化时,视图也会随之更新。这种自动的双向同步使得开发者能够更加便捷地管理数据和视图之间的交互。

二、Vue 3 响应式系统概述

Vue 3 中的双向绑定是基于响应式系统实现的。响应式系统的核心在于 Proxy 对象,它取代了 Vue 2.x 中的 Object.defineProperty,从而带来了更强大的功能和更好的性能。

Vue 3 的响应式系统包括以下几个核心部分:

  1. Reactive:将普通对象转换为响应式对象。

  2. Effect:用于依赖收集和副作用处理的函数。

  3. Track & Trigger:依赖收集和依赖触发的机制。

  4. Ref:对单一值的响应式封装。

三、Vue 3 双向绑定的实现原理

在 Vue 3 中,双向绑定的核心在于响应式数据和模板编译的结合。数据模型通过响应式系统实现数据变化的监听,而模板编译器将模板中使用到的数据与 DOM 进行绑定,当数据变化时,自动更新视图。

1. ReactiveRef

Reactive 是 Vue 3 提供的一个 API,用于创建一个深度响应式对象。它内部使用 Proxy 来监听对象的读取和写入操作。当某个响应式属性被读取时,track 函数会记录该依赖;当属性被修改时,trigger 函数会触发相应的更新操作。

Ref 则是对单一值进行响应式封装,它通过一个对象来保持一个值,并且在这个值发生变化时,通知所有依赖它的副作用函数。

import { reactive, ref, effect } from 'vue';const state = reactive({ count: 0 });
const name = ref('Vue 3');// 响应式地打印 count 的值
effect(() => {console.log(`Count is: ${state.count}`);
});// 修改 state.count,触发更新
state.count++;// 修改 name,触发更新
name.value = 'Vue 3.0';

2. TrackTrigger

Vue 3 的响应式系统通过 tracktrigger 两个函数来实现依赖收集和触发。

  • Track:当响应式数据的某个属性被访问时,track 函数会将当前正在运行的副作用函数记录为该属性的依赖。这样当该属性发生变化时,Vue 可以自动重新执行这些副作用函数。

  • Trigger:当响应式数据的某个属性被修改时,trigger 函数会找到该属性的所有依赖并重新执行,更新与之相关的 DOM。

底层代码实现如下:

let activeEffect;function effect(fn) {activeEffect = fn;fn();activeEffect = null;
}const targetMap = new WeakMap();function track(target, key) {if (!activeEffect) return;let depsMap = targetMap.get(target);if (!depsMap) {targetMap.set(target, (depsMap = new Map()));}let dep = depsMap.get(key);if (!dep) {depsMap.set(key, (dep = new Set()));}dep.add(activeEffect);
}function trigger(target, key) {const depsMap = targetMap.get(target);if (!depsMap) return;const dep = depsMap.get(key);if (dep) {dep.forEach(effect => effect());}
}function reactive(target) {return new Proxy(target, {get(target, key, receiver) {const result = Reflect.get(target, key, receiver);track(target, key);return result;},set(target, key, value, receiver) {const oldValue = target[key];const result = Reflect.set(target, key, value, receiver);if (oldValue !== value) {trigger(target, key);}return result;}});
}

在这个实现中,effect 函数用于收集依赖并执行副作用函数。track 函数负责依赖收集,而 trigger 函数负责依赖触发。

3. 模板编译与响应式系统的结合

Vue 3 的模板编译器会将模板转换为渲染函数,并在渲染函数中访问响应式数据。当渲染函数首次执行时,Vue 会收集所有与模板相关的响应式数据的依赖,这样当数据发生变化时,Vue 会自动重新执行渲染函数,更新视图。

const template = `<div>{{ state.count }}</div>`;
const render = compile(template);effect(() => {const vnode = render(state);// 将 vnode 渲染到 DOM
});

四、总结

Vue 3 的双向绑定机制通过响应式系统和模板编译器的紧密结合,实现了数据与视图之间的自动同步。ReactiveRefTrackTrigger 是响应式系统的核心,而 Proxy 的使用使得 Vue 3 的响应式系统更加灵活和高效。通过这种机制,Vue 3 能够提供更优的性能,并让开发者能够更加专注于业务逻辑的实现。

希望通过本文的详细解析,能够帮助你更好地理解 Vue 3 中双向绑定的底层原理,并在实际开发中更有效地运用这一强大特性。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • ARM/Linux嵌入式面经(二六):韶音
  • 【记录】MICCAI BraTs 2020数据集
  • shell脚本中$0 $1 $# $@ $* $? $$ 的各种符号意义详解
  • 小阿轩yx-Kubernetes Pod调度基础
  • 服务路由(Service Routing)
  • Eagle 4.0:强大插件加持的素材收集管理工具
  • 大数据ETL工具(Sqoop, DataX, Kettle)对比
  • 带有限制编辑的PDF文件怎么取消编辑限制
  • 3ds Max - 导出顶点色模型
  • 计算机网络速成(三)
  • 芯片后端之 PT 使用 report_timing 产生报告 之 常用命令
  • python办公自动化:使用`python-docx`插入与管理书签
  • 编译 buildroot 错误录
  • Open3D mesh 裁剪
  • 服务发现: Node.js + Eureka
  • 时间复杂度分析经典问题——最大子序列和
  • 03Go 类型总结
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Fabric架构演变之路
  • React Transition Group -- Transition 组件
  • react-native 安卓真机环境搭建
  • SOFAMosn配置模型
  • spring cloud gateway 源码解析(4)跨域问题处理
  • SpringCloud集成分布式事务LCN (一)
  • 安卓应用性能调试和优化经验分享
  • 解析 Webpack中import、require、按需加载的执行过程
  • 解析带emoji和链接的聊天系统消息
  • 删除表内多余的重复数据
  • 我的面试准备过程--容器(更新中)
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 大数据全解:定义、价值及挑战
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ‌‌雅诗兰黛、‌‌兰蔻等美妆大品牌的营销策略是什么?
  • #AngularJS#$sce.trustAsResourceUrl
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • #数据结构 笔记三
  • $GOPATH/go.mod exists but should not goland
  • (14)Hive调优——合并小文件
  • (BFS)hdoj2377-Bus Pass
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (转)四层和七层负载均衡的区别
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .NET面试题(二)
  • .sys文件乱码_python vscode输出乱码
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • @font-face 用字体画图标
  • @软考考生,这份软考高分攻略你须知道
  • [ C++ ] STL---string类的使用指南