Vue3中 ref 和 reactive 有什么区别

1.8k words

在 Vue3 中 refreactive 都是用于创建响应式数据的,但它们有一些关键区别和使用场景。

ref

  1. 单一值: ref 用于创建一个响应式引用,通常用于基本类型(如 stringNumber,Boolean)
  2. 访问值: 当你需要访问 ref 创建的响应式变量时,需要使用 .value 属性
1
2
const count = ref(0)
console.log(count.value)
  1. 模板中的简化: 在模板中,你不需要使用 .value ,vue 会自动解引用
1
2
3
4
<template>
<div>{{ count }}</div>
<!-- 自动解引用 -->
</template>
  1. 可重新赋值: 你可以通过 count.value = 1 赋予一个新值。
  2. 转换对象: 使用 ref 创建的响应式对象,在解构或传递到其他函数时,会失去其响应性。需要使用 toRefstoRef 来保持响应性。
  3. 保存 DOM 节点: 你可以通过 ref 将它与 DOM 元素绑定,从而在 JavaScript 中访问该 DOM 节点。这对操作 DOM、管理焦点等非常有用。
1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div ref="myDiv">Hello, Vue!</div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const myDiv = ref(null)

onMounted(() => {
console.log(myDiv.value) // 输出 DOM 元素
})
</script>

这里的 myDiv 就是一个 ref,它指向了模板中的 div 元素,myDiv.value 可以访问到该 DOM 节点。
此外,ref 也能用来保存 非响应式的复杂对象,比如 DOM 节点、第三方库的实例等,这些场景中 ref 会更灵活。

reactive

  1. 对象/数组: reactive 用于创建响应式对象或数组
  2. 访问值: 访问 reactive 创建的响应式对象就像访问普通对象一样。
1
2
const state = reactive({ count: 0 })
console.log(state.count) //0
  1. 不可重新赋值: 对 reactive 创建的响应式对象的根重新赋值(例如state = {}) 不会改变响应性。但其内部属性可以被修改。
  2. 嵌套响应性: 当你创建一个响应式对象,其内部嵌套的所有对象和数组也会自动变为响应式。
  3. 解构问题: 如果你解构一个使用 reactive 创建的响应式对象,解构出来的值将失去响应性。这与 ref 是相似的,但你可以使用 toRefstoRef 函数来解决这个问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { reactive, toRefs } from 'vue'

// 创建一个响应式对象
const state = reactive({
count: 0,
name: 'Vue3',
})

// 解构时失去响应性
const { count, name } = state
console.log(count) // 输出: 0, 但无法响应变化

// 使用 toRefs 来解决解构后的响应性丧失
const { count: reactiveCount, name: reactiveName } = toRefs(state)
console.log(reactiveCount) // 输出: 0,并保持响应性

总结

  • ref 适合创建单一/独立的值, 或者当你需要在模板中直接使用时
  • reactive更适用于复杂的嵌套的 数组/对象 (vue3利用proxy对于嵌套的复杂数据有懒加载处理)
  • 你可以使用 toReftoRefs 这两个辅助函数 对 refreactive 进行转换

选择 ref 还是取决reactive于具体的需求和你的个人喜好,一些开发者更倾向于使用 ref 来管理所有状态(包括数组和对象),因为可以保持代码的一致性。
也可以根据用例来决定使用 ref 还是 reactive

Comments