关键区别对比
| 特性 | ref | reactive |
|---|---|---|
| 可用于基本类型 | ✅ | ❌ |
| 可用于对象 | ✅ | ✅ |
| 可用于数组 | ✅ | ✅ |
访问值需要 .value |
✅ (JS中) | ❌ |
| 保持原始引用 | ❌ | ✅ |
ref 的用途
ref 可以用于任何类型的值,包括:
- 基本数据类型(字符串、数字、布尔值等)
- 对象(包括普通对象、数组等)
- 复杂数据结构
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)
总结
回答您的具体问题:
ref可以声明数组,没有问题ref更通用,适用于所有数据类型reactive只适用于对象类型- 主要区别在于访问方式(
.value)和替换整个对象的能力
在实际开发中,您可以根据具体需求选择:
- 需要响应式的基本类型值 → 使用
ref - 需要响应式的对象且不会整体替换 → 使用
reactive - 需要整体替换的对象 → 使用
ref - 不确定时 → 使用
ref(更安全通用)