vue3 - 02.ref全家桶

本文探讨了Vue3中的ref和shallowRef的区别,强调了它们不能混合使用以避免不必要的视图更新。同时介绍了triggerRef用于强制刷新视图的功能,并通过customRef展示了如何实现一个简单的防抖功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ref:

<template>
  <div>
    {{name}}
    <hr />
    <button @click="handleChange">change</button>
  </div>
</template>
<script setup lang='ts'>
  import { ref } from 'vue'
  type info = {
    name:string
  }
  const name = ref<info>({
    name:"xiaoming"
  })
  const handleChange = () => {
    name.value.name = "xiaohong"
  }
</script>
<style scoped>
</style>

isRef:判断当前是否为ref对象

<template>
  <div>
    {{name}}
    <hr />
    <button @click="handleChange">change</button>
  </div>
</template>
<script setup lang='ts'>
  import { isRef, ref } from 'vue'
  type info = {
    name:string
  }
  const name = ref<info>({
    name:"xiaoming"
  })
  const handleChange = () => {
    if(isRef(name)){
      alert(1)
    } else {
      alert(2)
    }
  }
</script>
<style scoped>
</style>

shallowRef:浅层次相应,和ref对比,ref是深层次相应

<template>
  <div>
    {{name}}
    <hr />
    <button @click="handleChange">change</button>
  </div>
</template>
<script setup lang='ts'>
  import { ref, shallowRef } from 'vue'
  type info = {
    name:string
  }
  const name = shallowRef<info>({
    name:"xiaoming"
  })
  const handleChange = () => {
    name.value.name = "xiaohong"
    console.log(name) // 输出是value值变了,但是视图没有变,只到.value
    // 这样写,才可以实现试图变化
    name.value = {
      name:"xiaohong123"
    }
  }
</script>
<style scoped>
</style>

ref和shallowRef不能一起使用,否则会造成视图更新,因为会调底层triggerRef

triggerRef:强制更新视图

<template>
  <div>
    {{name}}
    <hr />
    <button @click="handleChange">change</button>
  </div>
</template>
<script setup lang='ts'>
  import { ref, shallowRef,triggerRef } from 'vue'
  type info = {
    name:string
  }
  const name = shallowRef<info>({
    name:"xiaoming"
  })
  const handleChange = () => {
    name.value.name = "xiaohong123"
    triggerRef(name)
    console.log(name)
  }
</script>
<style scoped>
</style>

customRef:自定义ref

<template>
  <div>{{obj}}</div>
  <hr />
  <button @click="handleChange">change</button>
</template>
<script setup lang='ts'>
  import { ref, shallowRef,triggerRef,customRef } from 'vue'
  function myRef<T>(value:T){
    return customRef((track,trigger) => {
      return {
        get(){
          track()
          return value
        },
        set(newVal){
          value = newVal
          trigger()
        }
      }
    })
  }
  const obj = myRef<string>("小红")
  const handleChange = () => {
    obj.value = "小蓝"
  }
</script>
<style scoped>
</style>

我们可以用 customRef 写一个防抖的例子,比如我们疯狂的触发,只执行一次

<template>
  <div>{{obj}}</div>
  <hr />
  <button @click="handleChange">change</button>
</template>
<script setup lang='ts'>
  import { ref, shallowRef,triggerRef,customRef } from 'vue'
  function myRef<T>(value:T){
    let timer: any
    return customRef((track,trigger) => {
      return {
        get(){
          track()
          return value
        },
        set(newVal){
          clearInterval(timer)
          timer = setTimeout(() => {
            console.log("触发了")
            value = newVal
            timer = null
            trigger()
          },500)
        }
      }
    })
  }
  const obj = myRef<string>("小红")
  const handleChange = () => {
    obj.value = "小蓝"
  }
</script>
<style scoped>
</style>

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值