在 Vue3 <script setup> + 组合式 API 之 怎用使用响应式变量

什么是响应式?

Vue3 的响应式是:当更改响应式对象的值改变时,视图会随即自动更新。

ref()

ref() 返回一个响应式对象,可以用 value 属性来访问或更改对象的值。
ref 对象在模板中会自动解包,用变量名不需要加 .value 就能访问。

1
2
3
4
5
6
7
8
9
10
11
<script setup>
import { ref } from 'vue';

const say = ref('hi'); // 定义值为 hi 的响应式变量 say
say.value = 'hello'; // 把 say 的值改为 hello
</script>

<template>
<!-- 自动解包,不需要些成 {{ say.value }} -->
<p>{{ say }}</p>
</template>

reactive()

reactive() 函数可以创建一个响应式对象,可以用对象的属性来访问对象,也可以使用 Object.assign() 来改变对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script setup>
import { reactive } from 'vue'

const state = reactive({ count: 0 })

Object.assign(state, {count: 9}); // 用 Object.assign 更改,使用时应注意,Object.assign 为覆盖式浅拷贝值。

function increment() {
state.count++
}

</script>

<template>
<button @click="increment">
{{ state.count }}
</button>
</template>

reactive() 仅对 对象类型 有效(对象、数组和 Map、Set 这样的集合类型),而对 string、number 和 boolean 这样的 原始类型 无效。

readonly()

readonly() 返回一个原值的只读代理对象。

响应式数据源的侦听

组合式 API 通过如下函数定义侦听响应式数据源,详见官方文档

  • watch() 侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。
  • watchEffect() watch() 使用 immediate: true 选项时的别名,立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
  • watchPostEffect() watchEffect() 使用 flush: 'post' 选项时的别名。
  • watchSyncEffect() watchEffect() 使用 flush: 'sync' 选项时的别名。

ref()/reactive/非响应式变量该怎样选择?

响应式需要实时监听变量的状态,是需要系统开销的,所以不应该所有的变量都用响应式。
当页面因响应式变量变动而刷新时(包括隐藏、显示),很多时候非响应式变量值改动了也会跟着变,但并不是100%。
只要涉及到模板跟着实时更新的变量,都应该用响应式变量,反之则应该用飞响应式变量。

  • 当变量改动后,模板视图不需要跟着变的时候,不需要用响应式变量。
  • 当需要响应式,并且要覆盖全部的值来更改的时候,使用 ref,如列表数组、原始类型等。
  • 当值为对象(对象、数组、Map、Set 等集合类型)类型的时候,用 reactive

参考
1、响应式基础
2、深入响应式系统
3、响应式API:核心

在 Vue3 <script setup> + 组合式 API 之 怎用使用响应式变量

https://coderpan.com/front-end/vue3-sfc-composition-script-setup-reactivity.html

作者

CoderPan

发布于

2023-02-13

更新于

2024-05-08

许可协议

评论