Vue3 新特性
Vue3 新特性
Composition API (组合式)
Composition API 是 Vue3 引入的一种编写方式,核心目标是更好地组织和复用逻辑,解决 Vue2 的 Options API(选项式)在大型项目中逻辑分散的问题。
例如,一个简单的计数器组件
在 Vue2 中的写法为
export default {
data() {
return {
count: 0,
}
},
methods: {
increment() {
this.count++
},
},
watch: {
count(newVal) {
console.log('count changed:', newVal)
},
},
}使用 Vue3 的写法为
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
watch(count, (newVal) => {
console.log('count changed:', newVal)
})
</script>
<template>
<button @click="increment">{{ count }}</button>
</template>其中 计数器可以抽出
function useCounter() {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
}
// 在组件中使用
const { count, increment } = useCounter()相对于 Options API,Composition API 的优势在于:
- 集中组织逻辑
- 可复用性高
- 对 TypeScript 的类型推断支持度更高
- 组件的维护更方便
setup
setup() 是 Vue3 中新增的组合式 API 入口函数,官方给出的典型使用场景主要有两点:
- 需要在非单文件组件中使用组合式 API 时。
- 需要在基于选项式 API 的组件中集成基于组合式 API 的代码时。
基本使用
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
// 返回值会暴露给模板和其他的选项式 API 钩子
return {
count
}
},
mounted() {
console.log(this.count) // 0
}
}
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>setup() 有两个参数
- props:和标准的组件一致,一个 setup 函数的 props 是响应式的,并且会在传入新的 props 时同步更新。
- context:第二个参数是 Setup 上下文对象,会暴露在 setup 中常用的一些能力:
export default {
setup(props, context) {
// 透传 Attributes(非响应式的对象,等价于 $attrs)
console.log(context.attrs)
// 插槽(非响应式的对象,等价于 $slots)
console.log(context.slots)
// 触发事件(函数,等价于 $emit)
console.log(context.emit)
// 暴露公共属性(函数)
console.log(context.expose)
},
}setup 需要注意
- setup() 不包含对组件实例的访问权,在 setup() 顶层访问 this 会是 undefined
setup()应返回同步对象。只有组件作为Suspense后裔时,才允许使用async setup()。
<script setup> 是 setup() 的语法糖,也是单文件组件使用组合式 API 时的官方推荐写法。
<script setup>
// 变量
const msg = 'Hello!'
// 函数
function log() {
console.log(msg)
}
</script>
<template>
<button @click="log">{{ msg }}</button>
</template>等价于
<script>
import { defineComponent } from 'vue'
export default defineComponent({
setup() {
// 变量
const msg = 'Hello!'
// 函数
function log() {
console.log(msg)
}
// 暴露给模板使用
return {
msg,
log
}
}
})
</script>
<template>
<button @click="log">{{ msg }}</button>
</template>相对于普通的 <script>
<script setup> 主要优势如下:
- 更少的样板内容,更简洁的代码。
- 能够使用纯 TypeScript 声明 props 和自定义事件。
- 更好的运行时性能(模板会被编译为同一作用域内的渲染函数,避免渲染上下文代理对象开销)。
- 更好的 IDE 类型推导性能(减少语言服务从代码中抽取类型的额外成本)。
Teleport
Teleport 官方定义如下:
<Teleport>是一个内置组件,可将组件内部的一部分模板“传送”到该组件 DOM 结构外层的位置。
典型使用场景
- 弹窗(modal)
- 全屏遮罩层(overlay)
- 悬浮菜单(dropdown)
- tooltip、通知栏等不希望被 CSS 继承/干扰的元素
Teleport 解决的核心痛点是:逻辑代码和模板代码虽然位于同一单文件组件,但 DOM 可能渲染在层级较深的位置,导致样式受上层 CSS 干扰。
使用 Teleport 可以让 DOM 直接渲染到指定外层容器,降低上层样式污染风险。
Teleport 只改变 DOM 渲染位置,不改变组件逻辑关系。
核心实现机制如下:
被 Teleport 包裹的 DOM 会被打上特殊标记:
export const TELEPORT: unique symbol = Symbol(__DEV__ ? `Teleport` : ``)运行时会生成特殊 VNode,并在 patch 阶段(虚拟 DOM 转真实 DOM)识别为 TELEPORT 后走专门分支处理。
Suspense
<Suspense> 是 Vue3 新增的内置组件,用于在组件树中协调异步依赖处理。它允许上层等待下层多个嵌套异步依赖解析完成,并在等待阶段渲染加载状态。
渲染流程核心步骤
- 遇到
<Suspense>标签
- 编译器将其编译成 vnode,type 是内置组件
SuspenseImpl - 其子插槽
default和fallback分别作为slots.default和slots.fallback
- 执行 default 插槽
- Vue 会尝试执行 default 插槽中的组件 setup()
- 如果这些组件中的 setup() 返回了 Promise(或 await 表达式),Vue 会将它们加入等待队列
suspense.asyncDeps
- 渲染 fallback
- 当
suspense.asyncDeps > 0,Vue 会先渲染 fallback 插槽内容 - fallback 是实际插入 DOM 的元素(如
<Loading />)
- 等待异步内容完成
- 每个异步组件 resolve 后会调用
suspense.depsResolved(),减少计数 - 所有 asyncDeps 全部完成后,Vue 会:
- 卸载 fallback 插槽
- 挂载 default 插槽的实际渲染内容(即真实组件内容)
Fragment
相较于 Vue2 中 template 必须包含单一根节点的约束,Vue3 允许多个根节点。
当 template 中存在多个根节点时,Vue 会在运行时将其组织为 Fragment 结构。
响应系统重构
Vue 3 使用全新的响应式系统取代了 Vue 2 中的 Object.defineProperty,采用了 ES6 的 Proxy 技术,彻底重构响应式核心,使其更加灵活、高效、功能丰富。
核心变化:基于 Proxy 构建响应式对象
| Vue 版本 | 响应式实现方式 |
|---|---|
| Vue 2 | Object.defineProperty(递归劫持,难以监听新增/删除) |
| Vue 3 | Proxy(动态劫持,无需递归,支持新增/删除) |
核心 API 简介
| API 名称 | 作用描述 |
|---|---|
reactive() | 将对象变为响应式对象(深层) |
ref() | 创建响应式的基本类型(如字符串、数字等) |
computed() | 创建计算属性,自动依赖收集 |
watch() | 响应式侦听器,监听值的变化 |
effect() | Vue 内部依赖追踪的原始 API(不常用) |
背景
「Vue3 新特性」属于框架机制类主题,价值在于指导实际架构决策,而不是停留在 API 对比。
核心原理
建议从三层理解框架:编译期生成什么、运行时如何调度、更新阶段如何控制复杂度。
实现方式 / 示例
把机制映射到业务问题:组件粒度划分、状态归属边界、列表更新策略、异步渲染时机。
常见问题
- 只讨论语法差异,忽略调度模型差异。
- 性能问题归因笼统,缺少可观测数据。
- 对比结论缺乏适用场景,难以指导选型。
最佳实践
对每个结论补充“适用场景、成本、替代方案”,把知识沉淀为可执行的选型标准。
总结
围绕「Vue3 新特性」的关键是把框架认知转化为工程决策能力。
