vue3中ref和reactive的使用场景
一、核心区别
| 特性 | ref | reactive |
|---|---|---|
| 数据类型 | 基本类型 + 对象/数组(自动解包) | 仅对象/数组 |
| 响应式原理 | 通过 .value 触发响应 | 直接代理对象 |
| 模板中使用 | 自动解包(无需 .value) | 直接访问属性 |
| 解构/传递 | 保持响应性 | 需用 torefs 保持响应性 |
二、使用场景与案例
1. ref 的典型场景
(1) 管理基本类型值
import { ref } from 'vue'
// 计数器(数字)
const count = ref(0)
const increment = () => {
count.value++ // 修改值必须用 .value
}
// 开关状态(布尔值)
const isopen = ref(false)
const toggle = () => {
isopen.value = !isopen.value
}(2) 引用 dom 元素
<template>
<input ref="inputref" />
</template>
<script setup>
import { ref, onmounted } from 'vue'
const inputref = ref(null)
onmounted(() => {
inputref.value.focus() // 访问 dom 元素
})
</script>(3) 需要整体替换对象/数组
const user = ref({ name: 'alice', age: 25 })
// 替换整个对象
user.value = { name: 'bob', age: 30 }
const list = ref(['apple', 'banana'])
// 替换整个数组
list.value = ['orange', 'grape']2. reactive 的典型场景
(1) 复杂表单对象
import { reactive } from 'vue'
const form = reactive({
username: '',
password: '',
rememberme: false
})
// 直接修改属性(无需 .value)
form.username = 'john'(2) 嵌套数据结构
const nesteddata = reactive({
user: {
profile: {
name: 'alice',
address: {
city: 'shanghai'
}
}
}
})
// 深层嵌套修改仍保持响应性
nesteddata.user.profile.address.city = 'beijing'(3) 数组操作
const items = reactive(['a', 'b', 'c'])
// 直接修改元素
items[0] = 'z' // 响应式更新
items.push('d') // 使用数组方法三、关键操作指南
1. 正确赋值/修改
ref 示例:
const count = ref(0) // ✅ 正确修改 count.value = 10 // ❌ 错误!直接赋值会覆盖 ref 对象 count = 10
reactive 示例:
const state = reactive({ count: 0 })
// ✅ 正确修改属性
state.count = 10
// ❌ 错误!直接替换对象会失去响应性
state = { count: 20 }
// ✅ 保持响应性的对象替换方式
object.assign(state, { count: 20 })2. 处理响应式丢失
(1) 解构 reactive 对象
const state = reactive({ x: 1, y: 2 })
// ❌ 解构后失去响应性
const { x, y } = state
// ✅ 使用 torefs 保持响应性
const { x, y } = torefs(state)
x.value = 10 // 现在修改有效(2) 函数间传递
// ✅ 传递整个 reactive 对象
const user = reactive({ name: 'alice' })
updateuser(user)
function updateuser(userobj) {
userobj.name = 'bob' // 修改仍响应
}
// ✅ 传递 ref 对象
const count = ref(0)
increment(count)
function increment(numref) {
numref.value++
}四、性能与最佳实践
优先选择:
- 基本类型 →
ref - 复杂对象 →
reactive - 需要灵活替换 →
ref(即使存储对象)
注意事项:
- 避免在
reactive中嵌套ref(除非明确需要) - 对数组进行索引操作时,建议使用变更方法(
push/pop等) - 大型数据集考虑
shallowref/shallowreactive提升性能
五、综合对比案例
<script setup>
import { ref, reactive } from 'vue'
// ref 管理用户id(基本类型)
const userid = ref(123)
// reactive 管理用户详情(对象)
const userdetail = reactive({
name: 'alice',
permissions: ['read', 'write']
})
// 修改操作示例
const updateuser = () => {
// 修改 ref
userid.value = 456
// 修改 reactive 对象
userdetail.name = 'bob'
userdetail.permissions.push('delete')
}
// 替换整个对象的最佳实践
const resetuser = () => {
// ref 可以直接替换
userid.value = 0
// reactive 应该合并属性而非直接赋值
object.assign(userdetail, {
name: 'guest',
permissions: []
})
}
</script>通过以上案例可以看出:ref 更适合管理独立值和需要完全替换的场景,而 reactive 在处理复杂对象结构时更直观。根据具体需求灵活选择,可显著提升代码可维护性。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论