- 作者:老汪软件技巧
- 发表时间:2024-10-14 21:02
- 浏览量:
Vue 2 双向绑定详解
Vue 2 使用 Object.defineProperty 来实现响应式数据。当一个对象成为响应式后,它的属性就会被转换成 getter 和 setter,从而可以在属性被访问或修改时进行拦截。
数据劫持
在 Vue 2 中,当你创建一个新的 Vue 实例时,Vue 会使用一个名为 Observer 的类来遍历 data 对象的所有属性,并将它们转换为 getter 和 setter。例如:
Javascript
深色版本
function observe(value) {
if (!value || typeof value !== 'object') {
return;
}
new Observer(value);
}
var Observer = function Observer(value) {
this.value = value;
this.walk(value);
};
Observer.prototype.walk = function walk(obj) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
defineReactive(obj, keys[i]);
}
};
function defineReactive(obj, key, val) {
var dep = new Dep();
var childOb = !Vue.isPlainObject(val) ? null : observer(val);
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
if (Dep.target) {
dep.addSub(Dep.target);
}
return val;
},
set: function reactiveSetter(newVal) {
if (newVal === val || (newVal !== newVal && val !== val)) {
return;
}
val = newVal;
dep.notify();
}
});
}
上面的代码展示了如何使用 Object.defineProperty 来创建 getter 和 setter。每当访问或设置属性时,都会触发相应的函数。如果访问时有活跃的依赖(即 Dep.target 存在),则将其添加到依赖列表中;如果设置时属性的值发生了变化,则通知所有依赖更新。
示例代码
Javascript
深色版本
new Vue({
el: '#app',
data: {
message: 'Hello Vue 2!'
},
created() {
// 模拟输入事件,改变message
this.message = 'Changed!';
console.log(this.$el.querySelector('p').textContent); // 输出 "Changed!"
}
});
Html
深色版本
<div id="app">
<input type="text" v-model="message">
<p>{{ message }}p>
div>
Vue 3 双向绑定详解
Vue 3 使用了 Proxy 来实现响应式数据。相比 Vue 2 的 Object.defineProperty,Proxy 提供了一种更简洁的方式来拦截对象的访问和修改。
响应式系统
在 Vue 3 中,响应式系统由 reactivity 包提供,其中 ref 和 reactive 是两个主要的工具函数。ref 创建一个响应式引用类型,而 reactive 则直接使一个对象变成响应式的。
Javascript
深色版本
import { ref, reactive } from 'vue';
const state = reactive({ count: 0 });
state.count++; // 触发依赖更新
// 或者使用 ref
const count = ref(0);
count.value++; // 触发依赖更新
示例代码
Javascript
深色版本
import { ref } from 'vue';
export default {
setup() {
const message = ref('Hello Vue 3!');
// 模拟输入事件,改变message
message.value = 'Changed!';
console.log(message.value); // 输出 "Changed!"
return {
message
};
}
};
Html
深色版本
<template>
<div id="app">
<input type="text" v-model="message">
<p>{{ message }}p>
div>
template>
总结
Vue 2 使用 Object.defineProperty 来监听数据变化,而 Vue 3 则使用了 Proxy,这是一种更现代的方法,能够更自然地处理数据变化。两种方法的核心目标都是为了让数据变化能够自动反映到视图上,但 Vue 3 的实现更加简洁并且功能更加强大。