主题
Vue 3 升级日志
汇总 Vue 3.4 与 Vue 3.5 带来的模板语法简化、侦听器增强,以及新增的组合式 API。
一、Vue 3.4
新增功能
1. 模板语法简写
当属性名称与绑定的 JavaScript 变量名称相同时,可以进一步简化语法:
html
<!-- 与 :id="id" 相同 -->
<div :id></div>2. watch 只触发一次
watch 可以只监听一次,侦听器会在回调首次运行后自动停止:
ts
watch(
source,
(newValue, oldValue) => {
// 当 source 变化时,仅触发一次
},
{ once: true },
);二、Vue 3.5
新增功能
1. props 支持解构
3.5 之前先接收整个 props 对象,再逐个访问:
vue
<script setup lang="ts">
// 3.5 之前
const props = defineProps<{ name: string }>();
</script>3.5 之后可以解构使用:
vue
<script setup lang="ts">
// 3.5 之后
const { name } = defineProps<{ name: string }>();
</script>解构后的顶层 prop 保持响应性,但不支持深层解构:
ts
// 不支持深层解构
const {
obj: { a: b },
} = defineProps<{ obj: { a: { b: number } } }>();2. props 默认值可直接赋值
3.5 之前用 withDefaults 定义默认值:
vue
<script setup lang="ts">
// 使用外部导入的类型
import type { User } from "@/types/user";
const { name, age } = withDefaults(defineProps<User>(), {
name: "hello",
age: 10,
});
</script>3.5 之后在解构时直接设置默认值:
vue
<script setup lang="ts">
// 3.5 之后
const { name = "zhangsan" } = defineProps<{ name: string }>();
</script>3. watchEffect 支持暂停与恢复
watchEffect 的返回值新增 pause、resume,配合原有的 stop 控制侦听器:
ts
const { stop, pause, resume } = watchEffect(() => {});
// 暂停侦听器
pause();
// 稍后恢复
resume();
// 停止
stop();4. watch 增强
(1)deep 除了传入布尔值,还可以传入数字,代表监听对象到第几层。
(2)可暂停 / 恢复侦听器:
ts
const { stop, pause, resume } = watch(() => {});
// 暂停侦听器
pause();
// 稍后恢复
resume();
// 停止
stop();新增 API
1. useTemplateRef
相比 ref,操作 DOM 或子组件更直观。
模板 ref 的传统写法——模板中声明 ref,脚本里用同名 ref() 接收:
html
<img ref="el" class="logo" :src="Logo" alt="" />ts
const el = ref(null);useTemplateRef 通过名称显式关联模板中的 ref,操作 DOM 更直观:
html
<input ref="inputRef" />ts
const inputEl = useTemplateRef<HTMLInputElement>("inputRef");操作子组件时同样适用。传统写法:
html
<HelloWorld ref="helloWorldRef" />ts
const helloWorldRef = ref(null);useTemplateRef 写法:
html
<HelloWorld ref="helloWorldRef" />ts
const childRef = useTemplateRef("helloWorldRef");2. app.onUnmount()
注册一个回调函数,在应用卸载时调用:
ts
interface App {
onUnmount(callback: () => any): void;
}3. useId
为每个应用实例生成唯一 ID,在服务端与客户端渲染过程中保持一致,常用于 SSR 场景(如关联 label 与 input):
vue
<script setup>
import { useId } from "vue";
const id = useId();
</script>
<template>
<form>
<label :for="id">Name:</label>
<input :id="id" type="text" />
</form>
</template>4. onWatcherCleanup
新增的全局 API,用于在侦听器中注册清理回调:
ts
import { watch, onWatcherCleanup } from "vue";
watch(id, (newId) => {
const controller = new AbortController();
fetch(`/api/${newId}`, { signal: controller.signal }).then(() => {
// callback logic
});
onWatcherCleanup(() => {
// abort stale request
controller.abort();
});
});