Vue3中ref和reactive的使用场景详解

 更新时间:2025年04月17日 17:24:35   作者:堕落年代  
这篇文章主要介绍了Vue3中ref和reactive的使用场景,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Vue3中ref和reactive的使用场景

一、核心区别

特性refreactive
数据类型基本类型 + 对象/数组(自动解包)仅对象/数组
响应式原理通过 .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 在处理复杂对象结构时更直观。根据具体需求灵活选择,可显著提升代码可维护性。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue使用webSocket更新实时天气的方法

    vue使用webSocket更新实时天气的方法

    本文将结合实例代码,介绍vue使用webSocket更新实时天气的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • vite构建项目并支持微前端

    vite构建项目并支持微前端

    本文主要介绍了vite构建项目并支持微前端,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • vue 组件间的通信之子组件向父组件传值的方式

    vue 组件间的通信之子组件向父组件传值的方式

    这篇文章主要介绍了vue 组件间的通信之子组件向父组件传值的方式总结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • vue中自定义右键菜单插件

    vue中自定义右键菜单插件

    这篇文章主要为大家详细介绍了vue中自定义右键菜单插件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • vue 路由缓存 路由嵌套 路由守卫 监听物理返回操作

    vue 路由缓存 路由嵌套 路由守卫 监听物理返回操作

    这篇文章主要介绍了vue 路由缓存 路由嵌套 路由守卫 监听物理返回操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • VUE写一个简单的表格实例

    VUE写一个简单的表格实例

    在本篇文章里小编给大家整理的是关于VUE中表格的写法实例以及相关知识点内容,需要的朋友们可以参考下。
    2019-08-08
  • Vue项目的表单校验实战指南

    Vue项目的表单校验实战指南

    这篇文章主要介绍了Vue项目表单校验的相关资料,前端表单校验能减少无效请求,保护后端接口,使用ElementPlus表单组件进行校验,需要准备表单对象、规则对象并进行双向绑定,用户名、密码以及协议勾选等字段都需符合特定规则,需要的朋友可以参考下
    2024-10-10
  • vue实现集成腾讯TIM即时通讯

    vue实现集成腾讯TIM即时通讯

    最近在做商城类的项目,需要使用到客服系统,用户选择的腾讯IM即时通信,所以本文主要介绍了vue实现集成腾讯TIM即时通讯,感兴趣的可以了解一下
    2021-06-06
  • vue3第二次传递数据方法无法获取到最新的值的解决方法

    vue3第二次传递数据方法无法获取到最新的值的解决方法

    这篇文章主要介绍了vue3第二次传递数据方法无法获取到最新的值,本文通过实例图文相结合给大家详细讲解,感兴趣的朋友一起看看吧
    2025-04-04
  • vue.js评论发布信息可插入QQ表情功能

    vue.js评论发布信息可插入QQ表情功能

    这篇文章主要为大家详细介绍了vue.js评论发布信息可插入QQ表情功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08

最新评论