Object.defineProperty(obj, prop, descriptor)
Object.defineProperty 只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历。如果,属性值是对象,还需要深度遍历。
优点:
缺点:
- 只能劫持对象的属性(key值.Object.key()),因此需要对每个对象的每个属性进行遍历。
- 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。是通过重写数据的操作方法(push、unshift…)来对数组进行监听的。
- 不能对 es6 新产生的 Map,Set 这些数据结构做出监听。
vue2用Object.defineProperty(obj, prop, descriptor)的实现
let obj = { key:'cue' flags: { name: ['AAA', 'VVV', 'FFF'] }}functionobserver(obj) { if (typeof obj == 'object') { for (let key in obj) { defineReactive(obj, key, obj[key]) } }}functiondefineReactive(obj, key, value) { Object.defineProperty(obj, key, { get() { console.log('获取:' + key) return value }, set(val) { observer(val) console.log(key + "-数据改变了") value = val } })}observer(obj)
Proxy
Proxy 是 ES6 中新增的一个特性,翻译过来意思是“代理”,用在这里表示由它来“代理”某些操作,让我们能够以简洁易懂的方式控制外部对对象的访问。其功能非常类似于设计模式中的代理模式。可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。简而言之,Proxy 可以劫持整个对象,并返回一个新的对象。
优点:
- 可以直接监听对象而非属性。
- 可以直接监听数组的变化。
- 有多种拦截方法,不限于apply、ownKeys、deleteProperty、has等是Object.defineProperty 不具备的。
- 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改。
Proxy的拦截方法
get(target, propKey, receiver)set(target, propKey, value, receiver)has(target, propKey)deleteProperty(target, propKey)ownKeys(target)getOwnPropertyDescriptor(target, propKey)defineProperty(target, propKey, propDesc)preventExtensions(target)getPrototypeOf(target)isExtensible(target)setPrototypeOf(target, proto)apply(target, object, args)construct(target, args)
vue3用Proxy的实现
let obj = { key:'cue' flags: { name: ['AAA', 'VVV', 'FFF'] }}functionobserverProxy(obj) { const handler = { get(target, key, receiver) { console.log("获取:" + key); if (typeof target[key] === "object" && target[key] !== null) { // 如果是对象,就添加 proxy 拦截 return new Proxy(target[key], handler); } return Reflect.get(target, key, receiver); }, set(target, key, value, receiver) { console.log("设置:" + key); return Reflect.set(target, key, value, receiver); }, }; return new Proxy(obj, handler);}let newObj = observerProxy(obj);
vue3的具体使用<scriptlang="ts">import { defineComponent, setup } from'vue'exportdefault defineComponent({ setup(props, context) { //props父组件传的值 //在setup()里我们不能用this //vue2.0里的 this.$emit, this.$psrent, this.$refs在这里都不能用了。 //context就是对这些参数的集合 //context.attrs //context.slots //context.parent 相当于2.0里 this.$psrent //context.root 相当于2.0里 this //context.emit 相当于2.0里 this.$emit //context.refs 相当于2.0里 this.$refs let data = reactive({ message: "hello world" }); //响应式对象 let message = ref("hello world"); //响应式字符串 let arr = ref(['hello','world']); //响应式数组字符串 let username = computed(() => user.firstname + " " + user.lastname); //计算属性 const copy = readonly(original); //只读代理 ... }})</script> 以上是本期分享的全部内容,欢迎大家留言,一起讨论关于Vue2和Vue3的相关问题~
下期会给大家分享几种Python定时任务的方法,敬请期待~
欢迎各位关注、留言,大家的支持就是我的动力!
|