vue3中的ref、isRef、shallowRef、triggerRef和customRef

1.ref

接受一个参数值并返回一个响应式且可改变的 ref 对象。 ref 对象拥有一个指向内部值的单一属性 .value property ,指向内部值。

例:此时,页面上的 str1 也跟着变化

javascript 复制代码
<template>
  <div>
    <button @click="handleClick">点击</button>
  </div>
  <br />
  <div>str1:{{ str1 }}</div>
  <br />
</template>

<script setup lang="ts">
import { ref } from 'vue'

const str1 = ref('123')

const handleClick = () => {
  str1.value = '456'
  console.log(str1.value) // "456"
}
</script>

使用 ref 获取 dom 元素:

javascript 复制代码
<template>
  <div ref="divRef">
    <button @click="handleClick">点击</button>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'

const divRef = ref(null) // 注意:此处的变量名必须和标签上的属性名一致
onMounted(() => {
  console.log(divRef.value) // 输出 <div></div>
})
const handleClick = () => {}
</script>

结果:

2.isRef

检查一个对象是否为 ref 包装过的对象。

javascript 复制代码
<template>
  <div>
    <button @click="handleClick">点击</button>
  </div>
  <br />
  <div>str1:{{ str1 }}</div>
  <br />
</template>

<script setup lang="ts">
import { ref, isRef } from 'vue'

const str1 = ref('123')

const handleClick = () => {
  str1.value = '456'
  console.log(str1.value) // "456"
  console.log(isRef(str1)) // true
}
</script>

3.shallowRef

创建一个跟踪自身 .value 变化的 ref ,但不会使其值也变成响应式的。

javascript 复制代码
<template>
  <div>
    <button @click="handleClick">点击</button>
  </div>
  <br />
  <div>str1:{{ str1 }}</div>
  <br />
  <div>str2:{{ str2 }}</div>
  <br />
  <div>str3:{{ obj.name }}</div>
</template>

<script setup lang="ts">
import { ref, isRef, shallowRef } from 'vue'

const str1 = ref('123')
const str2 = shallowRef('123')
const obj = shallowRef({ name: '张三' })

const handleClick = () => {
  obj.value.name = '李四'
  console.log(obj.value) // {name: '李四'}
  // str2.value = '456'
}
</script>

运行结果:

页面展示:

需要注意的是: 应用 shallowRef 定义的基本值类型的数据,是具有响应式效果的,而引用类型不具有响应式效果。在 Vue3 中 shallowRef 函数源码中, value 具有响应式,而 value 中的属性不具有响应式。与 ref 函数不同的是, shallowRef 函数不会将其值转化为响应式对象,而是直接将其作为普通的对象或数组来处理。这意味着,当修改 shallowRef 对象的属性或数组的元素时, Vue3 将不会追踪这些变化。

注:由于 ref 和 triggerRef 在使用时都会调用 triggerRefValue ,而 triggerRefValue 会调用 triggerEffects 更新依赖,所以直接将 shallowRef 的依赖一起更新了。因此使用 shallowRef 定义的数据不应与使用 ref 定义的数据一起使用;应用 shallowRef 定义为 值类型的常量 被修改时与定义为 引用类型的常量 也不应一起使用!!!

javascript 复制代码
<template>
  <div>
    <button @click="handleClick">点击</button>
  </div>
  <br />
  <div>str1:{{ str1 }}</div>
  <br />
  <div>str2:{{ str2 }}</div>
  <br />
  <div>str3:{{ obj.name }}</div>
</template>

<script setup lang="ts">
import { ref, shallowRef, triggerRef, customRef, onMounted } from 'vue'
const str1 = ref('123')
const str2 = shallowRef('123')
const obj = shallowRef({ name: '张三' })

const handleClick = () => {
  obj.value.name = '李四'
  console.log(obj.value)
  str2.value = '456'
}
</script>

点击后结果:

点击事件部分代码改为:

javascript 复制代码
const handleClick = () => {
  str1.value = '456'
  console.log(str1.value)
  obj.value.name = '李四'
  console.log(obj.value)
}

点击后结果:

4.triggerRef

强制更新页面 dom ,使其具有响应式。

javascript 复制代码
<template>
  <div >
    <button @click="handleClick">点击</button>
  </div>
  <div>str3:{{ obj.name }}</div>
</template>

<script setup lang="ts">
import { ref, shallowRef, triggerRef } from 'vue'
const obj = shallowRef({ name: '张三' })

const handleClick = () => {
  obj.value.name = '李四'
  triggerRef(obj)
  console.log(obj.value)
}
</script>

点击后结果:

5.customRef

在 Vue3 中,提供了一个 customRef 函数,用于创建一个自定义的、可响应的引用对象。与 ref 和 shallowRef 不同的是, customRef 可以自定义 get 和 set 方法的实现逻辑,从而实现更加灵活的响应式行为。

使用 customRef 函数创建的引用对象与 ref 对象类似,也具有 value 属性,当读取这个属性时,会触发 get 方法的执行;当修改这个属性时,会触发 set 方法的执行,并且会触发相应的依赖更新。与 ref 对象不同的是, customRef 函数本身并不会对传入的初始值进行处理,而是将其直接作为 get 方法的返回值,需要自己手动处理。

javascript 复制代码
<template>
  <div>
    <button @click="handleClick">点击</button>
  </div>
  <div>name:{{ name }}</div>
</template>

<script setup lang="ts">
import { customRef} from 'vue'

function myRef<T = any>(value: T) {
  let timer: any
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newVal) {
        clearTimeout(timer)
        timer = setTimeout(() => {
          console.log('触发了set')
          value = newVal
          trigger()
        }, 500)
      }
    }
  })
}

const name = myRef<string>('张三')

const handleClick = () => {
  name.value = '李四'
}
</script>

点击500ms后结果:

相关推荐
GV191rLvq12 分钟前
基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
服务器·前端·asp.net
吠品18 分钟前
LangChain 里 tool_call_id 为空?一次 MCP 工具集成的排查记录
前端
柒和远方39 分钟前
Phase 7.4 学习博客:为什么多 API 项目需要 Swagger / OpenAPI
前端·后端·架构
张龙68741 分钟前
拼多多开放平台对接踩坑实录:从 CLIENT_ID 配置到 MD5 签名算法的完整填坑指南
前端
GuWenyue1 小时前
提示词彻底过时?一套上下文工程方案,3步让LLM落地生产,代码直接复用
前端·javascript·人工智能
柒和远方1 小时前
Phase 7.3 复盘:后台任务不只是“扔进队列”,还要能被看见
前端·后端·架构
2501_943782351 小时前
【共创季稿事节】 倒计时器:时分秒选择器与定时器的协同工作
前端·华为·harmonyos·鸿蒙·鸿蒙系统
奶油mm1 小时前
公司技术债堆积如山,我一人之力用 Vue3 偷换了整个前端架构
前端·vue.js
用户938515635071 小时前
深入理解 JavaScript 中的 this 与数据存储的奥秘
前端·javascript
Tian_Hang1 小时前
eclipse ditto 学习笔记
运维·服务器·开发语言·javascript·3d