vue响应式数据实现原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>夯实基础 Object.definedProperty()</title>
<!-- IMPORT CSS -->
</head>
<!-- dir(vm) :输出的属性,其中$开头是内置属性和方法,_开头是vue内置,没有$没有_是自己的 ; et msg: ƒ proxyGetter
set msg: ƒ proxysetter -->
<body>
<div id="app">
{{msg}} === {{year}} === {{obj.name}}
</div>
</body>
<!-- IMPORT JS -->
<script src="node_modules/vue/dist/vue.min.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
//=>响应式数据(基于Object.defineProperty进行处理过额GETTER/SETTER)
msg:'前端深度',
//=>Object.defineProperty(data,'obj',{get/set})
obj : {
//=>vue内置的observer/defineRective函数,会帮我么把所有的在data中初始化的属性都getter、setter(递归处理)
//name:'',
},
//=>ARR本身被getter、setter了,但是里面的每一项都没有处理,所以基于arr[index]=xxx修改值不能通知视图重新渲染=> vue对于数组是这样处理的: 把数组中的一些内置方法进行重写push/pop/unishift/shift/splice/reverse/sort,当我们调取这些方法的时候,vue会帮我们刷新视图
arr :[100]
},
created(){
this.year = 10;
},
mounted () {
setTimeout(() =>{
// this.msg = '前端基础深度化';
// this.year = 11;
//=>这才四修改obj的值,触发data中的setter
/// this.obj.name ='全栈开发';
//=>$set不仅仅是用来修改数据的,而且可以把被修改的属性基于defineProperty进行getter、setter
this.$set(this.obj, 'name' ,'人工智能');
},1000);
setTimeout(() =>{
this.obj.name = 'hehhehe~~'
},2000)
}
})
</script>
<script>
//=> Object.definedProperty():对一个对象中某一个属性的定义(处理)直接在方法上增加新属性 Object.defineProperty(obj, prop, descriptor)对象,属性名,描述
// let vm = new Vue({
// el: '#app',
// data: {
// //=>
// }
// })
let obj ={
name:'前端属性值改变',
age:10
};
//=>设置属性的getter(获得)、setter(设置) :我们可以再getter和setter中监听当前属性设置和获取的时候干什么 => 这也是vue2.0响应式数据(双向数据绑定)实现的原理,vue3.0采用的是proxy
Object.defineProperty(obj, 'name', {
//通过get获取name属性值改变name为HELLO world
get(){
console.log('GETTER');
return 'HELLO world'
},
set(value){
///通过get设置name属性值改变name为hahhahh~~
console.log('SETTER', value);
}
});
console.log(obj,name);
obj.name='hahhahh~~~';
/* Object.defineProperty(obj,'name',{
value:'前端',
//=>是否允许当前的属性被删除
//configurable:true
//=>是否为可枚举属性(列出每一项)
enumerable:true,
//=>控制当前属性是否被修改
writable:true
});
//=>enumerable
// for (let key in obj){
// console.log(key);
// }
//=>configurable
// delete obj.name;
// delete obj.age;
//=>writable
obj.name="云端";
console.log(obj);
*/
</script>
</html>
运行效果如下: