vue3中ref、reactive、shallowRef、 shallowReactive、toRaw、unref、toRef、toRefs、customRef使用与区别

ref

ref toRef
普通ref对象 特殊ref对象
不会和原始对象挂钩 创建的ref对象,与原始对象挂钩
重新渲染 不会触发渲染

-普通ref对象

  1. 不会和原始对象挂钩
  2. 重新渲染
    如下面的例子中, ref对象改变,视图已更新,原始数据json保持不变。



vue3中ref、reactive、shallowRef、 shallowReactive、toRaw、unref、toRef、toRefs、customRef使用与区别_第1张图片

toRef() -特殊ref对象,传入对象和属性
4. 创建的ref对象,与原始对象挂钩
5. 不会触发渲染




vue3中ref、reactive、shallowRef、 shallowReactive、toRaw、unref、toRef、toRefs、customRef使用与区别_第2张图片
toRefs()-批量处理toRef,传入一个对象




vue3中ref、reactive、shallowRef、 shallowReactive、toRaw、unref、toRef、toRefs、customRef使用与区别_第3张图片
customRef
创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和 trigger 函数作为参数,并且应该返回一个带有 get 和 set 的对象。

function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}

export default {
  setup() {
    return {
      text: useDebouncedRef('hello')
    }
  }
}

shallowReactive的简单实现

shallowReactive只对第一层监听变化

function shallowReactive(obj) {
   if (typeof obj === 'object') {
        return new Proxy(obj, {
            get(obj, key) {
                if (key in obj) {
                    return obj[key];
                } else {
                    console.warn('no this key:' + key)
                    return undefined;
                }
                
            },
            set(obj, key, val) {
                console.log('重新渲染')
                if (key in obj) {
                    obj[key] = val;
                } else {
                    console.warn('no this key:' + key)
                    obj[key] = val;
                }
                return true;
            }
        })
    } else {
        console.warn('this is not reactive :' + obj)
    }
}
let obj1 = shallowReactive({
  a: 12,
    b: [{
        c: 2
    }]
})
obj1.a++;
console.log(obj1)

结果:
在这里插入图片描述

 let obj1 = shallowReactive({
   a: 12,
    b: [{
        c: 2
    }]
})
obj1.b[0].c++;
console.log(obj1.b[0])

结果:
在这里插入图片描述

reactive简单实现

深度监听

function reactive(obj) {
   if (typeof obj === 'object') {
       if (obj instanceof Array) {
           obj.forEach((item, index) => {
               if (typeof item === 'object') {
                    obj[index] = reactive(item);
               }
              
           })
       } else {
           for (let key in obj) {
            if (typeof obj[key] === 'object') {
                obj[key] = reactive(obj[key])
            }
           }
       }

       return new Proxy(obj, {
            get(obj, key) {
                if (key in obj) {
                    return obj[key];
                } else {
                    console.warn('no this key:' + key)
                    return undefined;
                }
                
            },
            set(obj, key, val) {
                console.log('重新渲染')
                if (key in obj) {
                    obj[key] = val;
                } else {
                    console.warn('no this key:' + key)
                    obj[key] = val;
                }
                return true;
            }
        })
    } else {
        console.warn('this is not reactive :' + obj)
    }
}
let obj1 = reactive({
 a: 12,
   b: [{
       c: 2
   }]
})
obj1.b[0].c++;
console.log(obj1.b[0])

在这里插入图片描述

你可能感兴趣的:(vue,vue.js,json,javascript)