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

ref

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

-普通ref对象

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

<script>
import { ref } from 'vue'

export default {
  setup() {
    let json = { a: 12 }
    let b = ref(json.a)
    b.value++
    console.log('b', b.value)
    console.log('json', JSON.stringify(json))
    return {
      b
    }
  }
}
</script>

在这里插入图片描述

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

<template>
  <div>b = {{b}}</div>
</template>

<script>
import { ref, toRef } from 'vue'

export default {
  setup() {
    let json = { a: 12 }
    let b = toRef(json, 'a')

    setInterval(() => {
      b.value++
      console.log('b', b.value)
      console.log('json', JSON.stringify(json))
    }, 1000)

    return {
      b
    }
  }
}
</script>

在这里插入图片描述
toRefs()-批量处理toRef,传入一个对象

<template>
  <div>res = {{res}}</div>
</template>

<script>
import { ref, toRef, toRefs } from 'vue'

export default {
  setup() {
    let json = { a: 12, b: 5 }
    let res = toRefs(json) // 相当于{a: toRef(json, 'a'), b: toRef(json, 'b')}

    setInterval(() => {
      res.a.value++
      res.b.value++
      console.log('res.a', res.a.value, 'res.b', res.b.value)
      console.log('json', JSON.stringify(json))
    }, 1000)

    return {
      res
    }
  }
}
</script>

在这里插入图片描述
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])

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值