1.Object.defineProperty()
(1)这个方法是ES5新增的
(2)这个方法的作用是:给对象新增属性,或者设置对象原有的属性
(3)用法:Object.defineProperty(给哪个对象新增属性,‘新增的属性名是什么’,{给新增的属性设置相关的配置项key:value对})
补充:配置项有哪些?
①value配置项:给属性指定值
②writable配置项:设置该属性的值是否可以修改。true表示可以修改,false表示不能修改
③getter方法 配置项:不需要我们手动调用。当读取属性值的时候,getter方法被自动调用。
a.getter方法的返回值非常重要,这个返回值就代表这个属性它的值。
④setter方法 配置项:不需要我们手动调用。当修改属性值的时候,setter方法被自动调用。
a.setter方法上有一个参数,这个参数可以接收传过来的值
⑤当配置项当中有setter和getter的时候,value和writable配置项都不能写
<body> <script> // 一个普通对象 let phone = {} // 临时变量 let temp; // 给上面的phone对象新增一个color属性 Object.defineProperty(phone, 'color', { // value: '太空侠', // writable: true, get: function () { console.log('getter方法执行了'); return temp; }, set: function (val) { console.log('setter方法执行了'); temp = val; } }) </script> </body>
2.数据代理机制的实现
(1)什么是数据代理机制?
通过访问代理对象的属性来间接访问目标对象的属性。数据代理机制的实现需要依靠:Object.defineProperty()方法
(2)ES6新特性:在对象中的函数/方法 :function
是可以省略的
<body> <script> // 目标对象 let target = { name : 'zhangsan' } // 代理对象 let proxy = {} // 如果要实现数据代理机制的话,就需要给proxy新增一个name属性 // 注意:代理对象新增的这个属性的名字 和 目标对象的属性名要一致 Object.defineProperty(proxy, 'name', { get: function () { // 间接访问目标对象的属性 return target.name; }, set: function (val) { target.name = val; } }) </script> </body>
(3)属性名有(…)的代表是代理对象
3.响应式与数据劫持
3.1什么是响应式?
(1)修改data后,页面自动改变/刷新。这就是响应式。就像我们在使用excel的时候,修改一个单元格中的数据,
其它单元格的数据会联动更新,这也是响应式。
(2)属性名有(…)的就是响应式
(3)数据代理中getter和setter对应着什么?
数据代理:getter
数据劫持:setter
3.2 Vue 的响应式是如何实现的?
(1)数据劫持:Vue底层使用了Object.defineProperty,配置了setter 方法,当去修改属性值时setter方法则被自
动调用,setter 方法中不仅修改了属性值,而且还做了其他的事情,例如:重新渲染页面。setter方法就像半路劫
持一样,所以称为数据劫持。
(2)Vue 会给data中所有的属性,以及data属性中的属性,都会添加响应式。
(3)后期给vue实例动态追加的属性并没有添加响应式处理
<body> <div id="app"></div> <script> const vm = new Vue({ el: '#app', data: { msg: '响应式与数据劫持', name: 'jsckson', age: 20, a: { b: { c: 1 } } } }) // 后期给vue实例动态追加的属性并没有添加响应式处理 vm.$data.a.email = 'jackson@126.com' </script> </body>
(4)后期添加的属性,不会有响应式,怎么处理?
①Vue.set(目标对象,‘属性名’, 值)
②vm.$set(目标对象,‘属性名’, 值)
<body> <div id="app"></div> <script> const vm = new Vue({ el: '#app', data: { msg: '响应式与数据劫持', name: 'jsckson', age: 20, a: { b: { c: 1 } } } }) // Vue.set(vm.a,'email','3312@qq.com') vm.$set(vm.a,'email','331245@qq.com') </script> </body>
(5)不能直接给vm追加响应式属性,如:Vue.set(vm,‘x’,‘1’)
(6) Vue 没有给数组下标0,1,2,3…添加响应式,怎么处理?
调用Vue提供的7个API:
push()
pop()
reverse()
splice()
shift()
unshift()
sort()