最新版vue3+TypeScript开发入门到实战教程之toRefs与toRef实用技巧

toRefs与toRef概述

引用官网的一句话,将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象响应属性的ref。每个单独的ref都是使用toRef创建的。 反复读几次,发现还是有些懵,不易理解。通过一些事例,一步步解读,再回头看看这句,就不难理解。

给响应式对象结构解析赋值

对象结构解析,是很常用且舒适的获取对象成员的方法,若下代码

ini 复制代码
let fish = { name: '鲫鱼', price: 10 };
let { name, price } = fish;
console.log(name);
console.log(price);
name = '草鱼'
price = 20;
console.log(fish);

运行打印输出。我们发现,name,age能够得到fish中的值,但改变name、age并不能改变fish中的值。如下图: 若将响应式对象结构解析,获取到的成员变量是否是响应式的。

  • 定义响应式对象fish,let fish = reactive({ name: '鲫鱼', price: 10 })
  • 解析fish数据,let { name, price } = fish;
  • 模版分别渲染name,price,fish内数据
  • 改变name,price,fish内数据 具体代码如下:
xml 复制代码
<template>
  <h2>鱼类1:{{ fish.name }}</h2>
  <h2>价格1:{{fish.price  }}</h2>
  <h2>鱼类2:{{ name }}</h2>
  <h2>价格2:{{price  }}</h2>
  <button @click="changeName1">改变鱼类1</button>
  <button @click="changePrice1">改变价格1</button><br>
  <button @click="changeName2">改变鱼类2</button>
  <button @click="changePrice2">改变价格2</button>
</template>
<script setup>
import { reactive } from 'vue'
let fish = reactive({ name: '鲫鱼', price: 10 });
let { name, price } = fish;
function changeName1() {
  fish.name += '~'
  console.log(name);
}
function changeName2() {
  name += '~'
  console.log(fish.name)
}
function changePrice1() {
  fish.price += 1;
  console.log(price)
}
function changePrice2() {
  price += 1;
  console.log(fish.price)
}
</script>

运行点击改变鱼类1改变价格1 按钮,页面中只有鱼类1、价格1做响应变化。点击改变鱼类2改变价格2页面无任何变化。

  • 改变fish.name,页面响应改变,name不变
  • 改变fish.price,页面响应改变,price不变
  • 改变name,页面无响应,pirce.name不变
  • 改变price,页面无响应,price.name不变 结论是name只是从fish.name获取到值,与fish.name再没有关系,也不是响应式对象,同理price。 操作效果如下图

toRefs将响应式对象结构解析数据变成响应式

toRefs函数,将响应式对象内的数据,与解析后的数据划上一个等号,两者是同一个东西。如下代码

ini 复制代码
let fish = reactive({ name: '鲫鱼', price: 10 });
let { name, price } = toRefs(fish);
  • name是fish.name一个引用。name变,fish.name变;fish.name变,name变
  • 同理,price和fish.price也是如此。
  • name与price变成ObjectRefImpl 结构数据,ObjectRefImpl结构都是用ref定义的
  • 访问改变name、price数据时,都需加.value
xml 复制代码
<template>
  <h2>鱼类1:{{ fish.name }}</h2>
  <h2>价格1:{{fish.price  }}</h2>
  <h2>鱼类2:{{ name }}</h2>
  <h2>价格2:{{price  }}</h2>
  <button @click="changeName1">改变鱼类1</button>
  <button @click="changePrice1">改变价格1</button><br>
  <button @click="changeName2">改变鱼类2</button>
  <button @click="changePrice2">改变价格2</button>
</template>
<script setup>
import { reactive, toRefs } from 'vue'
let fish = reactive({ name: '鲫鱼', price: 10 });
let { name, price } = toRefs(fish);
function changeName1() {
  fish.name += '~'
  console.log(fish);
  console.log(name);

}
function changePrice1() {
  fish.price += 1;
}
function changeName2() {
  name.value += '~'
}

function changePrice2() {
  price.value += 1;
}
</script>

运行查看效果,分别点击四个按钮,页面都有变化,控制台打印输出fish与name,查看两者区别

toRef将响应式对象中的一个数据变成响应式

在实际应用开发中,可能并不需要将所有的成员变量都变成响应式,只需要其中一个,那就使用toRef。使用方法很简单

ini 复制代码
let fish = reactive({ name: '鲫鱼', price: 10 });
let name = toRef(fish,'name');
console.log(name);

打印name其结构如下:

toRefs返回值到底是什么

ini 复制代码
let fish = reactive({ name: '鲫鱼', price: 10 });
console.log(fish)
console.log(toRefs(fish))

如图 我们看看,fish下的name与price都变成ref定义的数据。回头再来看看官网说明,是否都明白了。 将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象响应属性的ref。每个单独的ref都是使用toRef创建的。

相关推荐
高级程序源32 分钟前
django大学生创新创业项目管理系统94923-计算机课程设计、毕业设计
javascript·vue.js·spring boot·后端·python·django·课程设计
lizz22761 小时前
Babel插件手册
javascript
VXbishe4 小时前
【课程设计】基于SpringBoot的乡村政务服务系统的设计与实现-计算机毕设77011
javascript·vue.js·spring boot·python·php·课程设计·政务
志尊宝4 小时前
Vue3 零基础每日笔记(037):动手封装 useMouse 与 useWindowSize——事件监听的标准模板
前端·javascript·vue.js·笔记·html5
shmily麻瓜小菜鸡4 小时前
TDD(测试驱动开发)详解
开发语言·javascript·typescript·node.js·ecmascript
BillKu5 小时前
vue3双向邦定:使用defineModel替换defineProps+defineEmits
vue.js
wcy03106 小时前
POST为什么会发送两次请求
javascript·ajax
志尊宝6 小时前
Vue3 零基础每日笔记(047):动态路由与路由参数——:id 传参、query 传参、props 解耦
前端·javascript·vue.js·笔记·html5
计算机毕设定制辅导-无忧学长6 小时前
《基于SpringBoot的中学教师数字胜任力测评网站的设计与实现》
java·vue.js·spring boot·mysql·中学教师数字胜任力测评网站
flash俊杰9 小时前
Vue 3 响应式陷阱与状态单例:从 TDZ 白屏到跨进程 Proxy 剥离
vue.js