Skip to content

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();
  });
});