湛蓝之海 发表于 2021-12-15 16:31:35

Vue2与Vue3的响应式区别

Object.defineProperty(obj, prop, descriptor)
Object.defineProperty 只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历。如果,属性值是对象,还需要深度遍历。
优点:

[*]兼容性好,支持 IE9。
缺点:

[*]只能劫持对象的属性(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)    }}}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 === "object" && target !== null) {       // 如果是对象,就添加 proxy 拦截      return new Proxy(target, 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定时任务的方法,敬请期待~
欢迎各位关注、留言,大家的支持就是我的动力!


https://blog.51cto.com/u_15345191/4805626
页: [1]
查看完整版本: Vue2与Vue3的响应式区别