1.vue2.x的响应式
实现原理:
- 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)
- 数组类型:通过重写更新数组方法来进行拦截。
Object.defineProperty(data,'shuxin',{
get(){}
set(){}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 模拟Vue2中的实现响应式 -->
<script>
let person = {
name:'礼盒',
age:19,
}
let p = {}
Object.defineProperty(p,'name',{
get(){
// 有人读取name
return person.name
},
set(value){
// 有人修改name
console.log('有人修改了name属性')
person.name = value
}
})
</script>
</body>
</html>
删除也不起作用 增加的sex属性也不是响应式的
遇到的一些问题:
- 新增属性、删属性、界面不会更新
- 直接通过下标修改数组时候,界面也不会自动更新
- 新增属性的时候界面没有更新耶,但是console出来的对象里面的属性是更新的。也有解决方法:this.delete/或 Vue.set Vue.delete
- 直接改变数组下标的时候界面也不会变化,也可以用this.$set 和Vue.set改变及splice改变界面
<template>
<div id="app">
<button @click="addLevel">增加工作职级属性</button>
<div v-if="job.level">{{job.level}}</div>
<button @click="deleteType">删除工作类型属性</button>
<div v-if="job.type">{{job.type}}</div>
<button @click="updateHobby">改变爱好的第一个元素</button>
<div>{{hobby}}</div>
</div>
</template>
<script>
import Vue from 'vue'
export default {
name: "App",
data(){
return {
job:{
type:'前端开发',
salary:'40K',
},
hobby:['唱','跳','rapper']
}
},
created(){
},
methods: {
addLevel(){
console.log(this.job)
// this.job.level = 'height'
// this.$set(this.job,'level','height')
Vue.set(this.job,'level','height')
console.log(this.job)
},
deleteType(){
console.log(this.job)
// delete this.job.type
// this.$delete(this.job,'type')
Vue.delete(this.job,'type')
console.log(this.job)
},
updateHobby(){
console.log(this.hobby)
// this.hobby[1] = '改'
// this.$set(this.hobby,1,'改')
// Vue.set(this.hobby,1,'改')
this.hobby.splice(1,1,'改')
console.log(this.hobby)
}
},
};
</script>
vue3.x
实现原理:
- 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的增删、读写
- 通过Reflect(反射):对被代理对象的属性进行操作。
<script>
let person = {
name: "礼盒",
age: 19,
};
let p = new Proxy(person,{});
</script>
<script>
let person = {
name: "礼盒",
age: 19,
};
let p = new Proxy(person,{
get(target,propName){
console.log(`读取${propName}属性`)
// return target[propName]
return Reflect.get(target,propName)
},
set(target,propName,value){
console.log(`修改了或增加了${propName}属性`)
// target[propName] = value
Reflect.set(target,propName,value)
},
deleteProperty(target,property){
console.log(`删除了${propName}属性`)
// return delete targetName[property]
return Reflect.deleteProperty(target,propName)
}
});
</script>