跳到主内容

vue3中的ref和reactive有什么区别?

· 3分钟阅读

我们都知道,vue3 可以用 refreactive 来定义响应式数组,但是为什么要提供两种定义方式呢?这两者本质的区别是什么?什么场景下使用 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

通过上面简单的例子可以对比得出

  1. ref 参数的值是一个原子类型,而 reactive 参数的值是一个对象,如果需要声明复杂的数据类型的时候,建议适用 reactive
  2. 在赋值方面,ref 通过 .value 来赋值,而 reactive 直接通过属性来赋值。

在 Javascript 世界里,原子类型有:StringNumberBigIntBooleanSymbolNullUndefined

可以将 ref 看成 reactive 的一个变形版本,这是由于 reactive 内部采用 Proxy 来实现,而 Proxy 只接受对象作为入参,这才有了 ref 来解决值类型的数据响应,如果传入 ref 的是一个对象,内部也会调用 reactive 方法进行深层响应转换