ref、reactive和computed的用法
1.ref
1.1 作用
用来创建一个基本类型(number、string、boolean...)或者引用类型(Array、Object...)的响应式数据对象。在 <script>
里访问必须加 .value
,在 <template>
里自动解包。
1.2 用法
// Vue3语法
<script setup>
import { ref } from 'vue'// ref:基本类型
const count = ref(0)
function add() {count.value++ // <script> 里必须 .value
}</script>
<template><button @click="add">count: {{ count }}</button> <!-- 模板里自动解包 -->
</template>
1.3 总结
优点:可以接收任何类型数据。
缺点:对于引用类型来说,不会对嵌套属性进行响应(数组里还有数组、对象里还有对象等)。
2.reactive
2.1 作用
用来将一个对象类型(Object、Array、Map、Set)变成深层次的响应式对象。
2.2 用法
<script setup>
import { reactive } from 'vue'// reactive:对象/数组
const user = reactive({ name: 'Tom', age: 18 })
function grow() {user.age++ // 直接属性访问,无需 .value
}
</script><template><button @click="grow">{{ user.name }} age: {{ user.age }}</button>
</template>
2.3 总结
优点:
reactive
创建的响应式对象是一个代理对象(Proxy),直接操作这个对象即可不用.value,并且是深层响应式(嵌套属性也是响应式的)。缺点:不适合用来包装基本类型(比如
number、boolean、string
),这种情况用ref
更合适。
3.computed
3.1 作用
用来定义一个基于其它响应式数据的计算属性,具备缓存特性(依赖不变就不重新计算)。并且永远返回一个 ref
(更准确地说是 ComputedRef
实例),不管里面包裹的是对象、数组还是基本类型。
3.2 用法
<script setup>
import { ref, computed } from 'vue'const price = ref(20)
const quantity = ref(2)
const total = computed(() => price.value * quantity.value)
</script><template><input v-model.number="price" type="number"><input v-model.number="quantity" type="number"><p>总价:{{ total }}</p>
</template>
3.3 总结
- 优点:具有缓存数据的功能,依赖没变,多次访问只算一次。
缺点:不能在
computed
中进行异步操作,并且computed
返回的是一个ref,不能对深层次的数据进行监听,只能通过在包一层reactive去或者使用watchEffect/watch进行监听。