vue双向绑定原理与实现
原理
Vue.js 的双向绑定是通过所谓的“数据驱动”架构实现的,这种架构的核心是“MVVM”(Model-View-ViewModel)模式。Vue.js 的双向绑定主要是通过以下几个步骤实现的:
-
响应式系统:Vue.js 使用了响应式系统,它通过Object.defineProperty()(Vue 2.x)或Proxy(Vue 3.x)来劫持(或观察)每个组件的data对象中的属性。当这些属性被访问或修改时,系统会通知视图更新。
-
依赖收集:当组件进行渲染时,Vue.js 会记录所有被访问的属性,这些属性被视为依赖。每个属性都有一个“依赖收集器”,当属性值发生变化时,它会通知所有依赖这个属性的地方。
-
发布-订阅模式:Vue.js 使用了发布-订阅模式,其中每个组件都有一个或多个观察者(Watcher)。当数据变化时,观察者会收到通知,并触发相应的更新函数来更新DOM。
-
v-model指令:Vue.js 提供了v-model指令,它是一个语法糖,用于在表单输入和应用状态之间建立双向绑定。当用户在输入框中输入内容时,v-model会更新相应的数据属性;反之,当数据属性发生变化时,v-model会更新输入框的显示内容。
-
更新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})参考
部分内容可能已过时
March7th