唠嗑部分
首先来说一说双向数据绑定,即数据变视图变,视图变数据变,在react中要实现这种功能,就要写受控表单了,而在vue中有一个指令,十分方便
v-model指令,这个指令可以说十分强大了,可以实现双向数据绑定,先看一下简单用法
<div id="app">
<input type="text" v-model="message">
<p>您输入的内容是: {{ message }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
message: ''
}
});
</script>
这样就能实现双向数据绑定了,那么你知道它是什么原理嘛?
言归正传
说到这个问题,就要分版本来说了,小白最近呢也是把vue3干完了,先说一下哈
在vue2.x当中是使用Object身上的一个方法实现的响应式,在vue3当中呢使用Proxy代理来实现响应式,下面我们具体分析一下
在vue2.x中呢,v-model指令是基于Object.defineProperty()
方法转换成getter/setter
,当数据发生变化时,setter函数会通知相关的视图进行更新,从而实现双向数据绑定。大家都知道,data函数返回的数据都是响应式的,这也是大前端框架的主要特点,那什么是响应式呢?
简单理解一下,当数据变了的时候,框架监测到,并且会帮我们更新页面
那根据上述理解,下面我们来写一段伪代码
let person = {
name: '张三',
age:20
}
let vm = {};
Object.defineProperty(vm, 'name', {
set(value) {
console.log(`有人新增或修改了vm身上的属性name,我要去更新页面了`)
person.name = value
},
get(){
return person.name
}
})
Object.defineProperty(vm, 'age', {
set(value) {
console.log(`有人新增或修改了vm身上的属性age,我要去更新页面了`)
person.age = value
},
get(){
return person.age
}
})
当vm的值变化时,会触发更新页面的逻辑,也就实现了响应式
那么这样会有什么问题,vue3为什么会优化掉呢?
1、首先这种方式每次只能监听一个对象的一个属性,那么对于复杂对象来说,底层就会使用循环处理,并且无法优化
2、这种方式不能够监听到属性的新增、删除
3、如果是数组类型,通过下标修改数据,也不能够检测到
注意,在vue2中
1、对象添加属性,不能直接添加,而是要通过this.$set(要操作的对象,添加的属性,值)
,或者Vue,set(要操作的对象,添加的属性,值)
,页面才能检测到,更新页面
2、对象删除属性,不能直接delete xxx.xx,而是要通过this.$delete(要操作的对象,删除的属性)
在vue3当中,响应式设计采用了proxy代理来实现,我们来看一段伪代码
let person = {
name: '张三',
age:20
}
const p = new Proxy(person, {
set(target, prop, value) {
console.log(`有人新增或修改了p身上的属性${prop},我要去更新页面了`)
Reflect.set(target, prop, value)
},
get(target, prop) {
console.log(`有人读取了p身上的属性${prop}`)
return Reflect.get(target, prop)
},
deleteProperty(target, prop) {
console.log(`有人删除了p身上的属性${prop},我要去更新页面了`)
return Reflect.deleteProperty(target, prop)
}
})
proxy方式可以一次性监视对象的所有属性,也能监听到属性的删除,对于数组类型下标修改也能检测到,解决了2.x留下的问题。
结语
1、使用Proxy实现的数据响应式系统更为灵活和高效,它可以代理整个对象
2、Object.defineProperty()方法只能代理单个对象属性,要通过循环或递归才能监听整个对象。
3、Vue2.x响应式原理是基于Object.defineProperty()实现的。
4、Vue3响应式原理是基于Proxy代理+Reflect实现的。
5、制作不易,一键三连再走吧,您的支持永远是我最大的动力!