响应式
这个词可能异常的火爆,比如响应式布局,响应式编程,“响应式”不难理解,针对事物改变做出自适应的变化,比如响应式布局就是根据页面显示大小对布局做出改变,而最近,看到了Vue.js的数据响应式,那就总结一下,有错误大家可以指出,我会加以改正(~ ̄▽ ̄)~。
正题:一、响应式体现
直接上代码!
<template>
<div>
<span>{{ name }}</span>
<button @click="modifyname">修改name</button>
</div>
</template>
<script>
export default {
data() {
return {
name: "ll",
};
},
methods: {
modifyname() {
this.name = "cc";
},
},
};
</script>
可以看到,这是一个简单的vue单文件中的内容,当我们点击按钮的时候,通过改变数据,来自动更新视图,所以,当我们使用Vue框架的时候,只需关注页面数据如何变化,因为数据变化后,视图也会自动更新,这让我们从繁杂的 DOM 操作中解脱出来,提高开发效率。
这里插入一个bug:
在使用vue的时候,data最好写成函数的形式,而不是对象,关于这点,在Vue文档中也只是进行了提及,具体原因在一次使用中,我发现到了bug:
data:{
n:0
}
这样写完全没问题,但是vue使用非完整版的时候,会进行
render(h) { return h(demo) },
如果你只是渲染了一次demo,并不会出现任何的错误,但是当你去渲染两个demo的时候,它会把data当作同样的对象进行处理,导致有些数据缺失,但是当data为
data() {
return {
n:0
};
},
此时,即使渲染两次demo,它也会把data作为单独的函数,不会造成上面的结果。
Object.defineProperty()
它和 Vue3 中的 proxy 可以来进行一下对比
Object.defineProperty()是针对单独的,个体的值,举个例子:
let person = {}
let personName = 'cc'
//在person对象上添加属性name,值为personName
Object.defineProperty(person, 'name', {
//但是默认是不可枚举的(for in打印打印不出来),可:enumerable: true
//默认不可以修改,可:wirtable:true
//默认不可以删除,可:configurable:true
get: function () {
console.log('触发了get方法')
return personName
},
set: function (val) {
console.log('触发了set方法')
personName = val
}
})
//当读取person对象的nam属性时,触发get方法
console.log(person.name)
//当修改personName时,重新访问person.name发现修改成功
personName = 'zs'
console.log(person.name)
// 对person.name进行修改,触发set方法
person.name = 'qq'
console.log(person.name)
当然,这只是一个值,那当我想要监听这个对象所有属性呢?
哦吼,你会发现,它表示很无奈,它必须去一个个遍历,一个个添加监听!而且,最致命的缺点是:
它 新增/删除元素 无法监听,必须去调用另外的api
所以,出现了 proxy
先来看个例子:
//定义一个需要代理的对象
let person = {
age: 0,
school: 'xx'
}
//定义handler对象
let hander = {
get(obj, key) {
// 如果对象里有这个属性,就返回属性值,如果没有,就返回默认值66
return key in obj ? obj[key] : 66
},
set(obj, key, val) {
obj[key] = val
return true
}
}
//把handler对象传入Proxy
let proxyObj = new Proxy(person, hander)
// 测试get能否拦截成功
console.log(proxyObj.age)//输出0
console.log(proxyObj.school)//输出xx
console.log(proxyObj.name)//输出默认值66
// 测试set能否拦截成功
proxyObj.age = 18
console.log(proxyObj.age)//输出18 修改成功
可以看出,Proxy代理的是整个对象,而不是对象的某个特定属性,不需要我们通过遍历来逐个进行数据绑定。
另外,其实深究的话,你会发现,proxy返回的其实还是一个proxy代理,它是层层代理。 基于上述Object.defineProperty()无法解决的问题,对 proxy 来说就是小菜一碟。
完结
简单记录一下自己在研究 Object.defineProperty() 和 proxy 的区别时候的重点,主要就是它们监听的方法,或者说范围大小的不同,文章有些地方没有去详细的举例子,可以参考一下MDN来理解。