Vue 响应式 API

2024-02-20

[[Vue]] 响应式 API 笔记。

ref()

ref 允许我们在一个特定的 DOM 元素或子组件实例被挂载后,获得对它的直接引用。

// `ref` API 的 TS 类型
function ref<T>(value: T): Ref<UnwrapRef<T>>;
// `ref` API 的返回值的 TS 类型
interface Ref<T> {
value: T;
}

定义

// 显式指定 `msg.value` 是 `string` 类型
const msg = ref<string>('Hello World!')
// 自动推导
const msg = ref('Hello World!)
// 初始化时如果不赋值,会自动添加 undefined 类型
const msg = ref<string>() // msg.value 为 undefined

computed()

只要原始数据没有改变,会立即返回之前的计算结果。可以优先考虑使用 computed,而不是 [[#watch()]]。

定义

// 只读
function computed<T>(
getter: (oldValue: T | undefined) => T,
debuggerOptions?: DebuggerOptions
): Readonly<Ref<Readonly<T>>>;
// 可写的
function computed<T>(
options: {
get: (oldValue: T | undefined) => T;
set: (value: T) => void;
},
debuggerOptions?: DebuggerOptions
): Ref<T>;

示例

只读:

const count = ref(1);
const plusOne = computed(() => count.value + 1);
console.log(plusOne.value); // 2
plusOne.value++; // 提示无法为 value 赋值,因为它是只读属性

reactive()

相对于 [[ref]],reactive 仅适用于[[JavaScript/syntax]][[JavaScript/syntax]]

function reactive<T extends object>(target: T): UnwrapNestedRefs<T>;

定义

import { reactive } from "vue";
// 对象
const myObj = reactive({ count: 0 }); // 定义
console.log(myObj.count); // 读取
myObj.count = 42; // 修改
// 定义数组
let myNumber = reactive([1, 2, 3, 42]);
myNumber.length = 0; // 重置
myNumber = []; // 重置(在 reactive 中可能存在问题)

toRef()

创建一个新的 Ref 变量,转换 Reactive 对象和数组的某个字段/值为 Ref 变量。

import { reactive, toRef } from "vue";
const myObj = reactive({ count: 42 });
// 第一个参数是 Reactive 对象,第二个参数是要转换的 key
const myObjRef = toRef(myObj, "count"); // 转换 count 字段为 Ref
// 数组
const myNumber = reactive([1, 2, 3, 42]);
const myNumberRef = toRef(myNumber, 3);
console.log(myNumberRef.value); // 返回 42

toRefs()

创建一个新的对象,它的每个字段都是 Reactive 对象各个字段的 Ref 变量。

import { reactive, toRef } from "vue";
// 对象转换
const myObj = reactive({ count: 42 });
const myObjRefs = toRefs(myObj);
// 数组转换
const myNumber = reactive([1, 2, 3, 42]);
const myNumberRefs = toRefs(myNumber);

isReactive()

检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。

import { reactive, isReactive } from "vue";
const myObj = reactive({ count: 0 }); // 定义
console.log(isReactive(myObj)); // 返回 true

watch()

侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。

import { watch } from 'vue'
watch(
source, // 必传,要侦听的数据源
callback, // 必传,侦听到变化后要执行的回调函数
options? // 可选,一些侦听选项
)
  • source
    • 一个函数,返回一个值
    • ref
    • 响应式对象
  • callback
// 单个来源
function watch<T>(
source: WatchSource<T>,
callback: WatchCallback<T>,
options?: WatchOptions
): StopHandle;
// 多个来源
function watch<T>(
sources: WatchSource<T>[],
callback: WatchCallback<T[]>,
options?: WatchOptions
): StopHandle;