花几分钟搞懂 toRef 和 toRefs !!

首先我们先介绍他们是什么???

在 Vue 中,toReftoRefs都是用于处理响应式数据的工具函数。

  • toRefs主要用于将一个响应式对象转换为一组响应式引用对象。这样做的好处在于,当你需要解构一个响应式对象时,使用toRefs可以确保解构后的属性仍然保持响应式。
  • toRef允许从一个已有的响应式对象中创建一个对特定属性的响应式引用。这个引用会保持与源对象属性的响应式连接,即当源对象的属性值发生变化时,通过toRef创建的引用也会同步更新。

上面的图片是Vue官方文档给出的解释,toRefs的实现一定程度是基于toRef上的,下面我们一起通过代码实例来理解这两个APi吧!

🐟toRefs

xml 复制代码
<template>
  <div>
    <h2> 姓名:{{ perosn.name }}</h2>
    <h2> 年龄:{{ person.age }}</h2>
    <button @click="changeName">增加~</button>
    <button @click="changeAge">加一</button>
  </div>
</template>

<script setup>
import { reactive } from 'vue'
let person = reactive({
  name: '张三',
  age: 18
})
const changeAge = () => {
  person.age += 1
}
const changeName = () => {
  person.name += '!'
}
</script>
<style lang="scss" scoped></style>

这段函数定义了一个含有属性nameagePerson对象,并且定义了两个button去修改nameage. 如果在这个时候你想使用解构赋值,将person中的name和age提取出来,

bash 复制代码
let { name, age } = person

是否这个时候我们就可以通过解构出来的age和person,不需要再使用前缀Person去调用了,

xml 复制代码
<template>
  <div>
    <h2> 姓名:{{ name }}</h2>
    <h2> 年龄:{{ age }}</h2>
    <button @click="changeName">增加~</button>
    <button @click="changeAge">加一</button>
  </div>
</template>
<script setup>
import { ref, reactive } from 'vue'
let person = reactive({
  name: '张三',
  age: 18
})
let { name, age } = person
const changeAge = () => {
  age += 1
  console.log(age);
}
const changeName = () => {
  name += '!'
  console.log(name);
}
</script>
<style lang="scss" scoped></style>

你会发现视图界面并没有更新,但是我在函数里写的console.log(age)console.log(name)他们的输出会随着函数的调用而改变,说明agename并不是没有改变,而是person.age``person.name没有改变,因为person才是响应式对象,而当对一个对象进行解构赋值时,会创建新的变量来引用对象的属性值。如果修改这些新变量的值,不会直接影响原始对象。所以就能很好的解释为什么 age,name的值明明改变了但是为什么视图界面不更新的原因.

这个时候Vue就提供api让我们去解决这个问题 首先我们介绍toRefs,看下面一段代码

xml 复制代码
<template>
  <div>
    <h2> 姓名:{{ name }}</h2>
    <h2> 年龄:{{ age }}</h2>
    <button @click="changeName">增加~</button>
    <button @click="changeAge">加一</button>
  </div>
</template>
<script setup>
import { toRefs, reactive } from 'vue'
let person = reactive({
  name: '张三',
  age: 18
})
let { name, age } = toRefs(person)
const changeAge = () => {
  age.value += 1
  console.log(age);
}
const changeName = () => {

  name.value += '!'
  console.log(name);
}
</script>
<style lang="scss" scoped></style>

我们在解构赋值的时候给person加上了toRefs,顾名思义,toRefs就是让解构出来的值变成ref所定义的响应式数据,所以需要加上value去修改他的值,console.log()出来的agename也验证了我们的想法

我们把 let { name, age } = toRefs(person)这行改为 let x = toRefs(person) ,然后输出一下 x 这个时候我们就可以理解上面说将一个响应式对象转换为一组响应式引用对象

🐟toRef

接下来我们介绍一下toRef,toRefs是把person这个响应式对象所有的key:value一次性都取出来,赋予响应式能力,toRef比他少了一个s,所以他是创建一个对特定属性的响应式引用,老规矩还是来看一段代码

  • 例如,假设有一个响应式对象person = reactive({ name: '张三', age: 18 }),可以使用const nameRef = toRef(person, 'name')创建一个对person对象中name属性的引用。
xml 复制代码
<template>
  <div>
    <p>姓名:{{ nameRef.value }}</p>
    <p>年龄:{{ person.age }}</p>
    <button @click="changeName">修改姓名</button>
  </div>
</template>

<script setup>
import { reactive, toRef } from 'vue';
const person = reactive({ name: '张三', age: 18 });
const nameRef = toRef(person, 'name');

const changeName = () => {
  nameRef.value = '李四';
};
</script>

简单来说就是toRef适合创建单个属性的响应式引用,这个引用是响应式的,当源对象的该属性发生变化时,通过toRef创建的引用也会同步更新。

🐟END

他们两兄弟适用于保持解构后的响应式 ,一个作用是作用是创建一个对源响应式对象特定属性的响应式引用,另一个是作用是创建一个对源响应式对象特定属性的响应式引用,大家可以通过后缀s很好的去区别,他们还可以取到简化代码结构的作用

相关推荐
Bigger1 小时前
Tauri (26)——托盘图标总对不上系统主题?一行 Template Image 搞定
前端·rust·app
kyriewen3 小时前
面试官问你:“AI 能写 80% 的代码了,公司为什么还需要你?”
前端·javascript·面试
甲维斯4 小时前
又升级咯!坦克大战2026,科技与复古并存!
前端·人工智能·游戏开发
搬砖的码农6 小时前
(08)为什么我的 Agent 一跑后台服务就卡死
前端·agent·ai编程
飘尘6 小时前
前端转全栈(Java 后端)必须要知道的:开发中的锁机制与分布式并发控制
前端·后端·全栈
亲亲小宝宝鸭6 小时前
前端性能监控:web-vitals
前端·性能优化·监控
前端切图崽_小郭6 小时前
虚拟滚动:静态 vs 动态的核心差异与实现?
vue.js
陆枫Larry7 小时前
可滚动页面背景填不满:`height: 100vh` vs `min-height: 100vh`
前端
Patrick_Wilson7 小时前
Squash Merge 的血缘陷阱:为什么删掉的代码又活了过来
前端·git·程序员