掌握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(更安全通用)
相关推荐
老前端的功夫1 小时前
前端Echarts性能优化:从卡顿到流畅的百万级数据可视化
前端·javascript
进击的野人1 小时前
深入解析localStorage:前端数据持久化的核心技术
前端·javascript
懵圈1 小时前
第2章:项目启动 - 使用Vite脚手架初始化项目与工程化配置
前端
Mh1 小时前
如何优雅的消除“if...else...”
前端·javascript
火鸟22 小时前
给予虚拟成像台尝鲜版十之二,完善支持 HTML 原型模式
前端·html·原型模式·通用代码生成器·给予虚拟成像台·快速原型·rust语言
逍遥江湖2 小时前
Vue3 + TypeScript 项目框架搭建指南
前端
lapiii3582 小时前
[前端-React] Hook
前端·javascript·react.js
小飞大王6662 小时前
JavaScript基础知识总结(六)模块化规范
开发语言·javascript·ecmascript
QuantumLeap丶2 小时前
《uni-app跨平台开发完全指南》- 07 - 数据绑定与事件处理
vue.js·ios·uni-app