Vue.js双向绑定实现原理详解
发布时间 - 2026-01-10 22:00:50 点击率:次Vue.js最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统。本文仅探究几乎所有Vue的开篇介绍都会提到的hello world双向绑定是怎样实现的。先讲涉及的知识点,再参考源码,用尽可能少的代码实现那个hello world开篇示例。

参考文章:https://www./article/100819.htm
一、访问器属性
访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过defineProperty()方法单独定义。
var obj = { };
// 为obj定义一个名为hello的访问器属性
Object.defineProperty(obj, "hello", {
get: function () {return sth},
set: function (val) {/* do sth */}
})
obj.hello // 可以像普通属性一样读取访问器属性
访问器属性的"值"比较特殊,读取或设置访问器属性的值,实际上是调用其内部特性:get和set函数。
obj.hello // 读取属性,就是调用get函数并返回get函数的返回值
obj.hello = "abc" // 为属性赋值,就是调用set函数,赋值其实是传参
get和set方法内部的this都指向obj,这意味着get和set函数可以操作对象内部的值。另外,访问器属性的会"覆盖"同名的普通属性,因为访问器属性会被优先访问,与其同名的普通属性则会被忽略(也就是所谓的被"劫持"了)。
二、极简双向绑定的实现
此例实现的效果是:随文本框输入文字的变化,span中会同步显示相同的文字内容;在js或控制台显式的修改obj.name的值,视图会相应更新。这样就实现了model =>view以及view => model的双向绑定,并且是响应式的。
以上就是Vue实现双向绑定的基本原理。
三、分解任务
上述示例仅仅是为了说明原理。我们最终要实现的是:
首先将该任务分成几个子任务:
1、输入框以及文本节点与data中的数据绑定
2、输入框内容变化时,data中的数据同步变化。即view => model的变化。
3、data中的数据变化时,文本节点的内容同步变化。即model => view的变化。
要实现任务一,需要对DOM进行编译,这里有一个知识点:DocumentFragment。
四、DocumentFragment
DocumentFragment(文档片段)可以看作节点容器,它可以包含多个子节点,当我们将它插入到DOM中时,只有它的子节点会插入目标节点,所以把它看作一组节点的容器。使用DocumentFragment处理节点,速度和性能远远优于直接操作DOM。Vue进行编译时,就是将挂载目标的所有子节点劫持(真的是劫持)到DocumentFragment中,经过一番处理后,再将DocumentFragment整体返回插入挂载目标。
五、数据初始化绑定
以上代码实现了任务一,我们可以看到,hello world已经呈现在输入框和文本节点中。
六、响应式的数据绑定
再来看任务二的实现思路:当我们在输入框输入数据的时候,首先触发input事件(或者keyup、change事件),在相应的事件处理程序中,我们获取输入框的value并赋值给vm实例的text属性。我们会利用defineProperty将data中的text劫持为vm的访问器属性,因此给vm.text赋值,就会触发set方法。在set方法中主要做两件事,第一是更新属性的值,第二留到任务三再说。
任务二也就完成了,text属性值会与输入框的内容同步变化:
七、订阅/发布模式(subscribe&publish)
text属性变化了,set方法触发了,但是文本节点的内容没有变化。如何让同样绑定到text的文本节点也同步变化呢?这里又有一个知识点:订阅发布模式。
订阅发布模式(又称观察者模式)定义了一种一对多的关系,让多个观察者同时监听某一个主题对象,这个主题对象的状态发生改变时就会通知所有观察者对象。
发布者发出通知 => 主题对象收到通知并推送给订阅者 => 订阅者执行相应操作
之前提到的,当set方法触发后做的第二件事就是作为发布者发出通知:“我是属性text,我变了”。文本节点则是作为订阅者,在收到消息后执行相应的更新操作。
八、双向绑定的实现
回顾一下,每当new一个Vue,主要做了两件事:第一个是监听数据:observe(data),第二个是编译HTML:nodeToFragement(id)。
在监听数据的过程中,会为data中的每一个属性生成一个主题对象dep。
在编译HTML的过程中,会为每个与数据绑定相关的节点生成一个订阅者watcher,watcher会将自己添加到相应属性的dep中。
我们已经实现:修改输入框内容 => 在事件回调函数中修改属性值 => 触发属性的set方法。
接下来我们要实现的是:发出通知dep.notify() => 触发订阅者的update方法 => 更新视图。
这里的关键逻辑是:如何将watcher添加到关联属性的dep中。
在编译HTML过程中,为每个与data关联的节点生成一个Watcher。Watcher函数中发生了什么呢?
首先,将自己赋给了一个全局变量Dep.target;
其次,执行了update方法,进而执行了get方法,get的方法读取了vm的访问器属性,从而触发了访问器属性的get方法,get方法中将该watcher添加到了对应访问器属性的dep中;
再次,获取属性的值,然后更新视图。
最后,将Dep.target设为空。因为它是全局变量,也是watcher与dep关联的唯一桥梁,任何时刻都必须保证Dep.target只有一个值。
至此,hello world双向绑定就基本实现了。文本内容会随输入框内容同步变化,在控制器中修改vm.text的值,会同步反映到文本内容中(但输入框还没有绑定,读者可以自己试试)。
完整代码:https://github.com/bison1994/two-way-data-binding
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Vue.js
# 双向绑定
# 深入理解vue.js双向绑定的实现原理
# 解析Vue2.0双向绑定实现原理
# 如何理解Vue的作用域插槽的实现原理
# Vue底层实现原理总结
# 浅谈vue中数据双向绑定的实现原理
# Vue中的基础过渡动画及实现原理解析
# Vue分页器实现原理详解
# Vue 2.0的数据依赖实现原理代码简析
# 浅析vue中的MVVM实现原理
# 浅析vue-router实现原理及两种模式
# Vue简单实现原理详解
# 绑定
# 输入框
# 的是
# 件事
# 过程中
# 多个
# 实现了
# 当我们
# 会为
# 将该
# 象中
# 我是
# 全局变量
# 就会
# 还没有
# 第一个
# 也就
# 一是
# 则是
# 又有
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
网站页面设计需要考虑到这些问题
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
软银砸40亿美元收购DigitalBridge 强化AI资料中心布局
原生JS获取元素集合的子元素宽度实例
Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】
Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?
Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
如何快速上传自定义模板至建站之星?
Laravel如何优化应用性能?(缓存和优化命令)
如何在Ubuntu系统下快速搭建WordPress个人网站?
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
nginx修改上传文件大小限制的方法
Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
再谈Python中的字符串与字符编码(推荐)
矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?
如何在IIS中配置站点IP、端口及主机头?
手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?
香港服务器部署网站为何提示未备案?
Laravel如何实现用户注册和登录?(Auth脚手架指南)
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
如何用AI帮你把自己的生活经历写成一个有趣的故事?
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
微信小程序 HTTPS报错整理常见问题及解决方案
米侠浏览器网页图片不显示怎么办 米侠图片加载修复
Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
如何用PHP工具快速搭建高效网站?
如何快速建站并高效导出源代码?
什么是javascript作用域_全局和局部作用域有什么区别?
如何在景安服务器上快速搭建个人网站?
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】
清除minerd进程的简单方法
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
Laravel如何使用Collections进行数据处理?(实用方法示例)
,网页ppt怎么弄成自己的ppt?
如何基于PHP生成高效IDC网络公司建站源码?
详解Android图表 MPAndroidChart折线图
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
Laravel怎么使用Intervention Image库处理图片上传和缩放
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
如何快速打造个性化非模板自助建站?

