理清vue2,vue3响应式原理
2023-06-13 09:13:00 时间
vue2和vue3响应式原理
vue2响应式原理
- 对象类型:通过
Object.defineProperty(obj,property,descriptor)
对属性的读取、修改进行拦截(数据劫持)。 obj绑定属性的目标对象property绑定的属性名descriptor属性(配置)对象 - 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。
- 存在问题:
- 新增属性、删除属性, 界面不会更新。
- 直接通过下标修改数组, 界面不会自动更新。
代码解构
对新对象p进行数据劫持,当访问到name属性时,会执行get()方法,从而返回源对象person的name属性。当修改p的name属性时,会执行set()方法,此时源对象的person中name属性就会同步更改
// 设置源数据
const person = {
name: "玩偶姐姐",
age: 24,
hobby: ["抽烟", "喝酒", "打豆豆"],
};
const p = {};
Object.defineProperty(p, "name", {
// 属性值
// value: 12,
//控制属性是否可以枚举,默认值是false
// enumerable: true,
//控制属性是否可以被修改,默认值是false
// writable: true,
//控制属性是否可以被删除,默认值是false
configurable: true,
// 当有人读取p的name属性时执行
get() {
console.log("读取了person的name属性");
return person.name;
},
// 当有人修改p的name属性时执行
set(value) {
console.log("修改了person的name属性");
person.name = value;
},
});
注意:在给对象设置 get 和 set 存取数据时,就不能设置属性值 value 和可读性 wriable,两者不可共存,使用 get 和 set 作为替代对属性进行读和取,所以只需要设置一个允许删除即可
v2响应式demo
通过object.defineproperty()来实现一个简单的响应式demo
<div>请输入 : <input type="text" /></div>
<br />
<textarea cols="30" rows="10"></textarea>
<script>
const obj = {
demo: "",
};
const newObj = {};
Object.defineProperty(newObj, "demo", {
configurable: true,
get() {
console.log("读取到到了数据");
return obj.demo;
},
set(value) {
console.log(`我同步了新数据${value}`);
obj.demo = value;
document.querySelector("input").value = value;
document.querySelector("textarea").value = value;
},
});
document.querySelector("input").addEventListener("input", function () {
newObj.demo = this.value;
});
document.querySelector("textarea").addEventListener("input", function () {
newObj.demo = this.value;
});
</script>
vue3响应式原理
- 通过Proxy(代理): new Proxy(target, handler),拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
target要使用
Proxy
包装的目标对象
(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。handler以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理p
的行为。 - 通过Reflect(反射): 对源对象的属性进行操作。
代码解构
通过proxy对person的代理,从而拦截对象的读取,修改删除属性操作,然后再通过p映射到person对象上面,从而达到响应数据
// 设置源数据
const person = {
name: "玩偶姐姐",
age: 24,
hobby: ["抽烟", "喝酒", "打豆豆"],
};
const p = new Proxy(person, {
//有人读取p的某个属性时调用
get(target, propName) {
console.log(`有人读取了p身上的${propName}属性`);
return Reflect.get(target, propName);
},
//有人修改p的某个属性、或给p追加某个属性时调用
set(target, propName, value) {
console.log(`有人修改了p身上的${propName}属性,我要去更新界面了!`);
Reflect.set(target, propName, value);
},
//有人删除p的某个属性时调用
deleteProperty(target, propName) {
console.log(`有人删除了p身上的${propName}属性,我要去更新界面了!`);
return Reflect.deleteProperty(target, propName);
},
});
当然,如果在不用reflect的情况下,也是可以实现数据响应的
// 设置源数据
const person = {
name: "玩偶姐姐",
age: 24,
hobby: ["抽烟", "喝酒", "打豆豆"],
};
const p = new Proxy(person, {
get(target, propName) {
console.log(`有人读取了p身上的${propName}属性`);
return target[propName];
},
set(target, propName, value) {
console.log(`有人修改了p身上的${propName}属性,我要去更新界面了!`);
return (target[propName] = value);
},
deleteProperty(target, propName) {
console.log(`有人删除了p身上的${propName}属性,我要去更新界面了!`);
return delete target[propName];
},
});
v3响应式demo
<div>请输入 : <input type="text" /></div>
<br />
<textarea cols="30" rows="10"></textarea>
<script>
const obj = {
demo: "",
};
const newObj = new Proxy(obj, {
// 有人读取p的某个属性时调用
get(target, propName) {
console.log(`有人读取了p身上的${propName}属性`);
return Reflect.get(target, propName);
},
//有人修改p的某个属性、或给p追加某个属性时调用
set(target, propName, value) {
console.log(`我同步了新数据${value}`);
Reflect.set(target, propName, value);
document.querySelector("input").value = value;
document.querySelector("textarea").value = value;
},
//有人删除p的某个属性时调用
deleteProperty(target, propName) {
return Reflect.deleteProperty(target, propName);
},
});
document.querySelector("input").addEventListener("input", function () {
newObj.demo = this.value;
});
document.querySelector("textarea").addEventListener("input", function () {
newObj.demo = this.value;
});
总结
以上就是v2v3响应式方面本人总结的内容,至于v3方面的为什么proxy要搭配reflet使用比较好,相关内容较多,请各位自行查阅吧,如有出错,欢迎各位大佬指出,小弟必将虚心求教
相关文章
- JeecgBoot 3.4.2 版本发布,Vue3版本大升级
- Vue3源码03: Vue3响应式核心原理
- Vue3源码07: 故事要从createApp讲起
- Cloud Studio尝鲜,在线构建vue3应用【玩转 Cloud Studio】
- Vue3模板语法--属性与表达式
- Vue3创建项目(三)Vuex配置
- 为什么vue3要选用proxy,好处是什么?
- Vue2.7正式发布,终于可以在Vue2项目中使用Vue3的特性了,真香~
- Vue3学习笔记(一)——MVC与vue3概要、模板、数据绑定与综合示例
- 尤玉溪回答:vue3是否汇聚所有前端开发人员的智慧都删不掉ref()函数?为什么svelte可以?
- 大佬,从Vue2快速上手Vue3,这份指南已经给大佬们准备好了。请您查收
- 手写 Vue3 响应式系统:核心就一个数据结构
- 带你深入Vue3响应式系统
- Vue3 响应式 API 之 ref 和 reactive
- VUE3+TS学习-项目搭建
- vue3+ts创建二维数组响应式变量及赋值
- Vue2.x中使用composition API,平滑过渡Vue3
- (二)第一个vue3.x应用
- golang + vue3+vite 构建后台管理系统笔记。
- 【Vue3】利用vite创建vue3项目
- Vue3+vite项目中如何动态导入并创建多个全局组件