Vue.js 3 - Composition API使用详解2(reactive、ref基本用法)
作者:hangge | 2026-04-25 09:46
若要使用 Options API 编写代码,可以在 data 选项中定义响应式数据。如果在 setup 函数中也需要定义响应式数据,那么可以使用 Vue.js3 提供的响应式 API:reactive 和 ref。 下面通过样例演示 reactive 和 ref 的使用。
(2)我们首先创建一个 ReactiveAPI.vue 组件,代码如下:
(3)接着在 App.vue 中使用 ReactiveAPI.vue 组件:
(4)运行效果如下,可以看到,counter 的值被显示出来,当单击“+1”按钮时,会回调 increment 函数来修改 counter 变量,这时,页面的数值会响应式刷新。这是因为使用 reactive 函数处理的数据,当数据被使用时,就会进行依赖收集;当数据发生改变时,所有收集到的依赖都会进行对应的响应式操作,如更新页面。
(4)修改 App.vue 组件,代码如下所示:
(5)运行效果如下图所示,可以看到,counter 的值被显示出来,当单击“+1”按钮时,会回调 increment 函数来修改 counter 变量,这时页面的数值会响应式刷新。
(3)浏览器运行效果如下:
二、reactive、ref 基本用法
1,reactive 函数使用
(1)如果想在 setup 函数中返回响应式数据,可以使用 reactive 函数。该函数可以将数据转换为响应式的,并且响应式是深层的--它影响所有嵌套属性。
提示:其底层原理基于 ES2015 的 Proxy 实现,所以 reactive 函数的返回值是一个对象的响应式代理。
- 首先从 vue 中导入 reactive 函数,并在 setup 中调用该函数。reactive 函数需要接收一个对象或数组类型的参数,并返回一个响应式对象。这里,我们向 reactive 函数传递一个对象,在该对象中定义 counter 属性。
- 接着,将 reactive 返回的响应式对象 state 作为 setup 函数的返回值,并在模板中显示 state 对象中的 counter 属性。
- 然后,当用户单击“+1”按钮时,会触发 increment 函数的回调,该函数实现了对 state 响应式对象中的 counter 属性的加 1 操作。
<template>
<div class="reactive-api" style="border:1px solid #ddd;margin:10px">
ReactiveAPI组件
<h4>当前计数: {{state.counter}}</h4>
<button @click="increment">+1</button>
</div>
</template>
<script>
import { reactive } from 'vue'; // 1.导入响应式api
export default {
setup() {
// 2.定义响应式数据
const state = reactive({
counter: 100
})
// console.log(state)
const increment = () => {
state.counter++; // 3.局部函数使用响应式数据
console.log(state.counter);
}
return {
state, // 4.返回响应数据
increment // 5.返回定义的方法(等同于在methods中定义方法)
}
}
}
</script>
(3)接着在 App.vue 中使用 ReactiveAPI.vue 组件:
<template>
<div class="app" style="border:1px solid #ddd;margin:4px">
App组件
<ReactiveAPI></ReactiveAPI>
</div>
</template>
<script>
import ReactiveAPI from './ReactiveAPI.vue';
export default {
components: {
ReactiveAPI
}
}
</script>
(4)运行效果如下,可以看到,counter 的值被显示出来,当单击“+1”按钮时,会回调 increment 函数来修改 counter 变量,这时,页面的数值会响应式刷新。这是因为使用 reactive 函数处理的数据,当数据被使用时,就会进行依赖收集;当数据发生改变时,所有收集到的依赖都会进行对应的响应式操作,如更新页面。
提示:事实上 data 选项返回的对象在 Vue.js3 内部也交给了 reactive 函数,将其变成响应式对象。
2,ref 函数使用
(1)reactive 函数对传入数据的类型是有限制的,必须是一个对象或数组类型。如果传入一个基本数据类型(String、Number、Boolean),则会出现警告。
- 例如,向 reactive 函数传递一个 Hello World 字符串,控制台会出现“value cannot be made reactive:Hello World”的警告。
(2)为了解决上述问题,Vue.js 3 提供了另一个响应式 API:ref,该 API 有如下特点:
- ref 函数接收一个值,返回一个响应式、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value。
- ref 对象内部值是通过该对象的 .value 属性维护的,比如可以通过.value 为该 ref 对象赋新值。
- 如果将对象分配为 ref 函数的值,则它将被 reactive 函数处理为深层的响应式对象。
(3)这里我们新建一个 RefAPI.vue 组件,代码如下所示:
- 首先从 vue 中导入 ref 函数,并在 setup 函数中调用该函数。在此处,我们向 ref 函数传递了一个基本数据类型:数字 100。
- 接着,将 ref 函数返回的 counter 响应式对象作为 setup 函数的返回值返回,并在模板中显示该响应式对象的内部值(value)。当用户单击“+1”按钮时,会调用 setup 函数返回的 increment 函数,该函数实现了对 counter 响应式对象内部值进行加 1 操作,并通过 .value 访问该对象的内部值。
注意:在模板中使用 ref 对象时,Vue.js3 会自动进行解包操作,不需要通过 .value 的方式访问内部值。但是,在 setup 函数内部不会自动解包,因此仍需要使用 .value 的方式访问内部值。
<template>
<div class="ref-api" style="border:1px solid #ddd;margin:10px">
RefAPI组件
<!-- 当我们在template模板中使用ref对象, 它会自动进行解包,不需要通过value属性访问 -->
<h4>当前计数: {{counter}}</h4>
<button @click="increment">+1</button>
</div>
</template>
<script>
import { ref } from 'vue'; // 1.导入响应式api
export default {
setup() {
// 2.定义响应式数据(ref函数接收基本数据类型的参数)
// counter是一个ref的可响应式的引用对象,可通过value属性获取和修改值
const counter = ref(100)
// console.log(counter)
const increment = () => {
counter.value++; // 3.局部函数修改响应式数据(不会自动解包)
console.log(counter.value); // 获取响应式数据
}
return {
counter, // 4.返回响应数据
increment // 5.返回定义的方法(等同于在methods中定义方法)
}
}
}
</script>
(4)修改 App.vue 组件,代码如下所示:
<template>
<div class="app" style="border:1px solid #ddd;margin:4px">
App组件
<RefAPI></RefAPI>
</div>
</template>
<script>
import RefAPI from './RefAPI.vue';
export default {
components: {
RefAPI
}
}
</script>
(5)运行效果如下图所示,可以看到,counter 的值被显示出来,当单击“+1”按钮时,会回调 increment 函数来修改 counter 变量,这时页面的数值会响应式刷新。

附:嵌套在其他对象中的 ref 对象使用效果
(1)ref 对象如果嵌套在普通对象或者 reactive 响应式对象中时,要注意:
- 如果普通对象包含 ref 对象,那么在模板中引用普通对象中的 ref 对象时,会自动解包。
- 如果 reactive 响应式对象包含 ref 对象,那么在模板中引用 reactive 响应式对象中的 ref 对象时,也会自动解包。
(2)我们将前面的 RefAPI.vue 组件代码修改成如下:
<template>
<div class="ref-api-other" style="border:1px solid #ddd;margin:10px">
RefAPIOther组件(演示ref的浅层解包)
<h4>当前计数: {{ counter }}</h4>
<!-- 如果普通对象包裹的是ref对象时,那么info中的ref对象可以解包 -->
<h2>当前计数: {{ info.counter }}</h2>
<!-- 如果最外层包裹的是一个reactive可响应式对象, 那么info中的ref对象可以解包 -->
<h2>当前计数: {{ reactiveInfo.counter }}</h2>
<button @click="increment">+1</button>
</div>
</template>
<script>
import { reactive, ref } from 'vue'; // 1.导入响应式api
export default {
setup() {
// 2.定义响应式数据
let counter = ref(100);
// 普通对象包含ref响应式对象
const info = {
counter
}
// reactive响应式对象包含ref响应式对象
const reactiveInfo = reactive({
counter
})
const increment = () => {
counter.value++;
console.log(counter.value);
}
return {
counter,
info,
reactiveInfo,
increment
}
}
}
</script>
(3)浏览器运行效果如下:

全部评论(0)