642 字
3 分钟

vue双向绑定原理与实现

原理#

Vue.js 的双向绑定是通过所谓的“数据驱动”架构实现的,这种架构的核心是“MVVM”(Model-View-ViewModel)模式。Vue.js 的双向绑定主要是通过以下几个步骤实现的:

  1. 响应式系统:Vue.js 使用了响应式系统,它通过Object.defineProperty()(Vue 2.x)或Proxy(Vue 3.x)来劫持(或观察)每个组件的data对象中的属性。当这些属性被访问或修改时,系统会通知视图更新。

  2. 依赖收集:当组件进行渲染时,Vue.js 会记录所有被访问的属性,这些属性被视为依赖。每个属性都有一个“依赖收集器”,当属性值发生变化时,它会通知所有依赖这个属性的地方。

  3. 发布-订阅模式:Vue.js 使用了发布-订阅模式,其中每个组件都有一个或多个观察者(Watcher)。当数据变化时,观察者会收到通知,并触发相应的更新函数来更新DOM。

  4. v-model指令:Vue.js 提供了v-model指令,它是一个语法糖,用于在表单输入和应用状态之间建立双向绑定。当用户在输入框中输入内容时,v-model会更新相应的数据属性;反之,当数据属性发生变化时,v-model会更新输入框的显示内容。

  5. 更新DOM:当数据变化时,Vue.js 会生成一个“虚拟DOM树”,并与上一次的虚拟DOM树进行比较(这个过程称为“diff”)。然后,Vue.js 只更新实际发生变化的部分,这种高效的更新策略称为“异步更新队列”,它可以减少不必要的DOM操作,提高性能。

总结来说,Vue.js 的双向绑定是通过响应式系统和发布-订阅模式实现的,它允许开发者以声明式的方式编写代码,而不需要手动操作DOM。这种机制使得状态管理变得更加简单,同时也提高了应用的可维护性。

实现#

vue2- Object.defineProperty 版本

const data = {
text: 'default',
}
const input = document.getElementById('input')
const span = document.getElementById('span')
Object.defineProperty(data, 'text', {
// 数据变化 -> 修改视图
set(newVal) {
input.value = newVal
span.innerHTML = newVal
},
})
// 视图变化 -> 修改数据
input.addEventListener('keyup', function (e) {
data.text = e.target.value
})

vue3- proxy 版本

// 数据
const data = {
text: 'default',
}
const input = document.getElementById('input')
const span = document.getElementById('span')
const handler = {
// 数据变化 -> 修改视图
set(target, key, value) {
target[key] = value
input.value = value
span.innerHTML = value
},
}
const proxy = new Proxy(data, handler)
input.addEventListener('keyup', function (e) {
proxy.text = e.target.value
})

参考#

手写vue实现双向绑定

vue双向绑定原理与实现
https://march7th.online/blog/posts/0007-vue双向绑定原理与实现/
作者
Yiguo
发布于
2024-06-02
许可协议
CC BY-NC-SA 4.0
最后更新于 2024-06-02,距今已过 524 天

部分内容可能已过时

目录