我们都知道,vue3 可以用 ref
和 reactive
来定义响应式数组,但是为什么要提供两种定义方式呢?这两者本质的区别是什么?什么场景下使用 ref
呢?什么场景下使用 reactive
呢?我们来一探究竟。
基本用法
为了搞清楚两者的区别,我们先来看看 ref
的使用方法。举个例子 🎱
<template>
<h1>{{ title }}</h1>
</template>
<script>
export default {
setup() {
let title = "1024nav.com";
setTimeout(() => {
title = "hello world";
}, 3000);
return { title };
},
};
</script>
我们在 setup()
中定义了一个 title
属性,这个属性的值是一个字符串。接下来三秒后,我们把 title
的值改成了 hello world
。
可以看出,三秒后界面的 title
并不会变成 hello world
,而是会继续保持原来的值。这是因为 title
不是一个响应式属性,它是一个普通的属性。我们使用 ref
来实现响应式属性。
<script>
import { ref } from "vue";
export default {
setup() {
let title = ref("1024nav.com");
setTimeout(() => {
// 这里需要使用 `.value` 来赋值
title.value = "hello world";
}, 3000);
return { title };
},
};
</script>
如果使用 reactive
来实现上述功能,该怎么写呢?
<script>
import { reactive } from "vue";
export default {
setup() {
const data = reactive({
title: "1024nav.com",
});
setTimeout(() => {
data.title = "hello world";
}, 3000);
return { data };
},
};
</script>
ref vs reactive
通过上面简单的例子可以对比得出
ref
参数的值是一个原子类型,而reactive
参数的值是一个对象,如果需要声明复杂的数据类型的时候,建议适用reactive
。- 在赋值方面,
ref
通过.value
来赋值,而reactive
直接通过属性来赋值。
在 Javascript 世界里,原子类型有:
String
、Number
、BigInt
、Boolean
、Symbol
、Null
、Undefined
。
可以将 ref
看成 reactive
的一个变形版本,这是由于 reactive
内部采用 Proxy
来实现,而 Proxy
只接受对象作为入参,这才有了 ref
来解决值类型的数据响应,如果传入 ref
的是一个对象,内部也会调用 reactive
方法进行深层响应转换