vue2响应式原理
Objedct.defineproperty
Objedct.defineproperty给对象定义属性
有三个参数,对象,属性名,配置项。
1 | Object.defineproperty(person,’age’,{value:18}) |
给person对象添加了age属性,值为18。
- 但是通过该方法增加的属性不可枚举,用Object.keys(person)获取不到;
- 不可被修改,在浏览器里定义person.age=19,查看person,里面数据还是18;
- 在Object.defineproperty方法里增加enumerable属性设置为true可以让修改的属性可被遍历到;
- 增加writable属性设置为true可以让属性可被修改;
- 增加configurable属性设置为true可以让属性可被删除;
1 | Object.defineproperty(person,’age’,{ |
- 如果定义value:number,number被修改后,如再定义number=19,
本来age已经被赋值过了,除非再赋值一遍:person.age=number,不然age还是18
这时用get方法,获取数据时会调用get方法,
1 | get (){ |
- 这样不用再给value赋值,get帮忙赋值了。
- (这种情况是改number,age也会变,如果改person.age,age还是不会变,需要用到set方法)
1 | set(value){ |
- Set修改了number的值,此时的value(那能不能直接改value的值呢,这样get也不用,set也不用)值应该还是18,等查看age的时候调用get方法,会让age显示为number的值
数据代理
用Object.defineproperty可以做数据代理(通过第二个对象来操作第一个对象里的数据)(通过get和set,在vue实例vm里加上data里的属性,这样可以直接用name,而不用_data.name了)。
缺点
Object.defineproperty只能get和set,读取和修改,如果新增和删除,虽然数据修改了,但是监测不到,页面不更新,
需要用
this.$set(this.person.’sex’.’女’
)或Vue.set(this.person.’sex’.’女’)
来新增
用this.$delete(this.person.’sex’’)
或Vue.set(this.person.’sex’)
来删除还有,通过下标修改数组, 界面不会自动更新,需要用this.$set或splice