最新版vue3+TypeScript开发入门到实战教程之ref与reactive的实战区别用法

概述

上节详细 说明ref、reactive如何定义使用响应式数据。总结如下:

  • ref定义基础类型数据
  • reactive定义对象数据
  • 但ref也可以定义对象类型的数据。但底层基于reactive实现 ref定义对象类型数据,底层用reactive实现, 但两者区别在何处,本文将详细说明

ref使用对象类型的数据定义响应式

  • 新建组件Fish
  • 创建响应式对象fish,数组fishs
  • 显示、修改响应式对象fish数据、fishs第一条数据
xml 复制代码
<template>
  <h2>鱼类:{{ fish.name }}</h2>
  <h2>价格:{{fish.price  }}</h2>
  <button @click="changeName">改变鱼</button>
  <button @click="addPrice">涨价</button>
  <h3>鱼的列表</h3>
  <ul>
    <li v-for="item in fishs" :key="item.id">
      {{ item.name }}:{{ item.price }}
    </li>
  </ul>
  <button @click="changeFirstPrice">改变第三条鱼的价格</button>

</template>
<script setup>
import { ref } from 'vue'
let fish = ref({ name: '鲫鱼', price: 10 });
let fishs = ref([
  {id:'txdi01',name:'鲫鱼',price:10},
  {id:'txdi02',name:'鲤鱼',price:20},
  {id:'txdi03',name:'草鱼',price:30},
])
function changeName() {
  fish.value.name = '草鱼';
  console.log(fish);
  console.log(fish.value);

}
function addPrice() {
  fish.value.price += 10;

}
function changeFirstPrice() {
  fishs.value[0].price += 10;
}
</script>

用ref定义的响应式对象,需要用.value去访问赋值。访问页面,发现他与reactive定义的响应式对象是一样的,除了reactive不需要用.value访问。如图 在点击按钮改变鱼,打印输入fish和fish.value,发现fish使用RefImpl定义,但 fish.value使用Proxy定义的对象,这与使用reactive定义是一样的。使用ref定义的响应式对象,底层使用reactive实现的。

ref对比reactive区别

从使用整体看

  • ref定义可以是基础数据、对象类型数据
  • reactive定义只能是对象类型数据

从细微之处看两者区别

  • ref创建的响应式对象,必须使用.value
  • reactive是深层次响应对象
  • reactive重新分配一个新对象,会丢失响应式

ref与reactive实际项目使用原则

  • 基本类型数据,必须使用ref
  • 简单的对象,不需要层级太深,ref、reactive都可以
  • 层级较深的对象,推荐使用reactive 以上使用原则,简单归纳,基本数据使用ref、对象使用reactive。但实际要清楚两者在深层次对象使用区别。

如何正确理解reactive重新分配一个新对象会流失响应式

reactive重新分配一个新对象会流失响应式是官方的说明。猛一看有些懵。我们从事例代码中去理解这句话的含义。事例中,定义let fish = reactive({ name: '鲫鱼', price: 10 }),创建5个按钮

  • 改变鱼的种类,fish.name = '草鱼';
  • 改变鱼的价格,fish.price += 10;
  • 方式一改变整个鱼,fish={ name: '鲤鱼', price: 30 }
  • 方式二改变整个鱼,fish = reactive({ name: '鲤鱼鱼', price: 40 });
  • 方式三改变整个鱼,Object.assign(fish,{ name: '带鱼', price: 50 }) 运行查看效果,发现,点击按钮方式一改变整个鱼、方式二改变整个鱼,页面无任何变。方式一、方式二都是重新给fis分配一个新的对象,导致fish丢失响应式。方式三是将新对象数据重新分配给fish,所以可以。 当fish丢失响应式数据后,再给fish重新赋值,页面也无法改变,也不在具有响应式。 细看图中的操作:

详细代码

xml 复制代码
<template>
  <h2>鱼类:{{ fish.name }}</h2>
  <h2>价格:{{fish.price  }}</h2>
  <button @click="changeName">改变鱼的种类</button>
  <button @click="addPrice">改变鱼的价格</button>
  <div>
    <button @click="changeallfish1">方式一改变整个鱼</button>
    <button @click="changeallfish2">方式二改变整个鱼</button>
    <button @click="changeallfish3">方式三改变整个鱼</button>
  </div>

</template>
<script setup>
import { reactive } from 'vue'
let fish = reactive({ name: '鲫鱼', price: 10 });
function changeName() {
  fish.name = '草鱼';

}
function addPrice() {
  fish.price += 10;

}
function changeallfish1() {
  fish={ name: '鲤鱼', price: 30 }

}
function changeallfish2() {
 fish = reactive({ name: '鲤鱼鱼', price: 40 });


}
function changeallfish3() {
  console.log('sadsd')
  Object.assign(fish, { name: '带鱼', price: 50 })
  console.log(fish);

}
</script>

ref定义的响应式对象重新分配一个新对象会怎样

  • 使用.value赋值,是响应式
  • 直接赋值,流失响应式 看事例
xml 复制代码
<template>
  <h2>鱼类:{{ fish.name }}</h2>
  <h2>价格:{{fish.price  }}</h2>
  <button @click="changeallfish1">方式一改变整个鱼</button>
  <button @click="changeallfish2">方式二改变整个鱼</button>
</template>
<script setup>
import { ref } from 'vue'
let fish = ref({ name: '鲫鱼', price: 10 });
function changeallfish1() {
  fish.value={ name: '鲤鱼', price: 30 }

}
function changeallfish2() {
 fish = ref({ name: '鲤鱼鱼', price: 40 });
}
</script>
相关推荐
夜焱辰7 小时前
浏览器端 Agent 的文件版本管理:不用 Git,基于 OPFS + SQLite 自己造了一个
前端·人工智能
梦想的颜色7 小时前
TypeScript 完全指南(下):从类型体操到生产级配置
前端·javascript·typescript
Hi~晴天大圣9 小时前
npm使用介绍
前端·npm·node.js
888CC++9 小时前
如何在 C 语言中进行程序调试?
前端·javascript·算法
喵个咪10 小时前
基于 Taro 的 Headless CMS 多端前端架构:技术解析与二次开发导引
前端·react.js·taro
狂炫冰美式10 小时前
你还在古法PPT吗,试试HTML呢?免费编辑导出工具给 xdm 放这了
前端·后端·github
万少10 小时前
未来组织的分水岭不是员工数量,而是人才密度
前端·后端·面试
任磊abc11 小时前
nextjs16配置eslint+prettier
前端·eslint·nextjs·prettier
x***r15111 小时前
Another-Redis-Desktop-Manager.1.3.7安装步骤详解(附Redis可视化连接与Key管理教程)
前端·bootstrap·html
Captaincc11 小时前
你真的知道自己把 AI 用在了哪里吗?这是 Vibe Usage 想回答的问题
前端·vibecoding