掌握Vue2转Vue3, Options API 转 Composition API

关键区别对比

特性 ref reactive
可用于基本类型
可用于对象
可用于数组
访问值需要 .value ✅ (JS中)
保持原始引用

ref 的用途

ref 可以用于任何类型的值,包括:

  1. 基本数据类型(字符串、数字、布尔值等)
  2. 对象(包括普通对象、数组等)
  3. 复杂数据结构
javascript 复制代码
import { ref } from 'vue'

// 基本类型
const count = ref(0)
const name = ref('Vue')
const isChecked = ref(true)

// 对象类型
const user = ref({
  name: 'John',
  age: 30
})

// 数组类型
const items = ref([1, 2, 3])
const userList = ref([
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' }
])

// 在模板中使用(不需要.value)
// <div>{{ count }}</div>
// <div>{{ user.name }}</div>
// <div>{{ items.length }}</div>

// 在 JavaScript 中使用(需要.value)
console.log(count.value) // 0
console.log(user.value.name) // 'John'
console.log(items.value.length) // 3

// 修改值
count.value = 1
user.value.name = 'Jane'
items.value.push(4)

reactive 的用途

reactive 只能用于对象(包括数组和 Map、Set 等集合类型):

javascript 复制代码
import { reactive } from 'vue'

// 对象
const user = reactive({
  name: 'John',
  age: 30
})

// 数组
const items = reactive([1, 2, 3])

// 集合类型
const map = reactive(new Map())
const set = reactive(new Set())

// 在模板中使用(不需要.value)
// <div>{{ user.name }}</div>
// <div>{{ items.length }}</div>

// 在 JavaScript 中使用(不需要.value)
console.log(user.name) // 'John'
console.log(items.length) // 3

// 修改值
user.name = 'Jane'
items.push(4)

实际应用建议

何时使用 ref:

javascript 复制代码
// 1. 基本数据类型
const count = ref(0)
const name = ref('Vue')

// 2. 当你需要替换整个对象时
const user = ref({
  name: 'John',
  age: 30
})

// 可以直接替换整个对象
user.value = { name: 'Jane', age: 25 }

// 3. 数组需要整体替换时
const items = ref([1, 2, 3])
items.value = [4, 5, 6] // 替换整个数组

何时使用 reactive:

javascript 复制代码
// 1. 对象属性会频繁修改,但对象本身不会替换
const user = reactive({
  name: 'John',
  age: 30,
  address: {
    city: 'Beijing'
  }
})

// 修改属性
user.name = 'Jane'
user.address.city = 'Shanghai'

// 2. 数组元素会频繁修改,但数组本身不会替换
const items = reactive([1, 2, 3])

// 修改数组元素
items[0] = 10
items.push(4)
items.splice(1, 1)

解构响应式对象的问题

当解构 reactive 对象时会失去响应性:

javascript 复制代码
// 错误示例 - 失去响应性
const user = reactive({ name: 'John', age: 30 })
const { name, age } = user // name 和 age 不再是响应式的

// 正确做法 - 使用 toRefs
import { reactive, toRefs } from 'vue'

const user = reactive({ name: 'John', age: 30 })
const { name, age } = toRefs(user) // name 和 age 仍然是响应式的

对于 ref 对象的解构:

javascript 复制代码
// ref 对象解构需要这样处理
const user = ref({ name: 'John', age: 30 })
const name = computed(() => user.value.name)
const age = computed(() => user.value.age)

总结

回答您的具体问题:

  1. ref 可以声明数组,没有问题
  2. ref 更通用,适用于所有数据类型
  3. reactive 只适用于对象类型
  4. 主要区别在于访问方式(.value)和替换整个对象的能力

在实际开发中,您可以根据具体需求选择:

  • 需要响应式的基本类型值 → 使用 ref
  • 需要响应式的对象且不会整体替换 → 使用 reactive
  • 需要整体替换的对象 → 使用 ref
  • 不确定时 → 使用 ref(更安全通用)
相关推荐
橙序员小站10 分钟前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
炫饭第一名3 小时前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
王晓枫3 小时前
flutter接入三方库运行报错:Error running pod install
前端·flutter
符方昊3 小时前
React 19 对比 React 16 新特性解析
前端·react.js
ssshooter3 小时前
又被 Safari 差异坑了:textContent 拿到的值居然没换行?
前端
曲折3 小时前
Cesium-气象要素PNG色斑图叠加
前端·cesium
Forever7_3 小时前
Electron 淘汰!新的桌面端框架 更强大、更轻量化
前端·vue.js
不会敲代码14 小时前
前端组件化样式隔离实战:React CSS Modules、styled-components 与 Vue scoped 对比
css·vue.js·react.js
Angelial4 小时前
Vue3 嵌套路由 KeepAlive:动态缓存与反向配置方案
前端·vue.js
jiayu4 小时前
Angular学习笔记24:Angular 响应式表单 FormArray 与 FormGroup 相互嵌套
前端