vue3重点

你系统、详细地整理Vue3的核心重点知识,覆盖从基础到进阶的关键内容,方便梳理学习脉络和掌握核心用法。

一、Vue3核心升级与优势

先明确Vue3相比Vue2的核心变化,这是理解后续知识点的基础:

  1. 架构重构:基于Monorepo管理源码,拆分为vue-corecompilerreactivity等独立包,体积更小(按需引入)、可维护性更高。
  2. 组合式API(Composition API):替代Options API的部分场景,解决大型组件中逻辑复用和代码分散的问题。
  3. 响应式系统重构:用Proxy替代Vue2的Object.defineProperty,支持数组、对象动态新增属性、Map/Set等复杂数据类型的响应式。
  4. 更好的TypeScript支持:源码全部用TS重写,开发者编写代码时能获得更完善的类型提示。
  5. 性能优化:编译阶段优化(静态节点提升、PatchFlags)、虚拟DOM重写,渲染性能提升约55%,内存占用减少约50%。
  6. 新特性:Teleport(瞬移组件)、Suspense(异步加载占位)、多根节点组件、Vite适配等。

二、Vue3基础核心

1. 项目创建(两种主流方式)

Vue3推荐用Vite(极速冷启动),也兼容Vue CLI:

1
2
3
4
5
6
7
8
9
# Vite创建(推荐)
npm create vite@latest my-vue3-project -- --template vue
cd my-vue3-project
npm install
npm run dev

# Vue CLI创建(需CLI 4.5+)
vue create my-vue3-project
# 选择Vue3版本

2. 根组件与入口文件变化

Vue3的入口创建方式和Vue2不同,支持多根节点:

1
2
3
4
5
6
7
<!-- App.vue(多根节点示例) -->
<template>
<!-- Vue3支持多根节点,无需外层div包裹 -->
<header>头部</header>
<main>主体</main>
<footer>底部</footer>
</template>
1
2
3
4
5
6
7
8
9
10
// main.js(Vue3入口)
import { createApp } from 'vue' // 替代Vue2的new Vue()
import App from './App.vue'

const app = createApp(App)
// 全局配置(替代Vue2的Vue.config)
app.config.errorHandler = (err) => { console.error(err) }
// 全局注册组件/指令(链式调用)
app.component('GlobalComp', GlobalComp).directive('focus', focusDirective)
app.mount('#app') // 替代$mount('#app')

三、核心重点:组合式API(Composition API)

这是Vue3最核心的知识点,解决Options API“逻辑碎片化”问题,建议优先掌握:

1. setup函数(组合式API的入口)

  • 执行时机:组件创建前(beforeCreate之前),此时thisundefined
  • 入参:props(响应式,不能解构)、context(包含attrs、emit、slots,非响应式)。
  • 返回值:对象(模板可直接使用)、渲染函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<template>
<div>{{ count }} {{ doubleCount }}</div>
<button @click="add">+1</button>
</template>

<script>
import { ref, computed } from 'vue'
export default {
props: {
initCount: { type: Number, default: 0 }
},
setup(props, context) {
// 1. 响应式变量(基础类型)
const count = ref(props.initCount)

// 2. 计算属性
const doubleCount = computed(() => count.value * 2)

// 3. 方法
const add = () => {
count.value++ // ref定义的变量需通过.value访问
context.emit('count-change', count.value) // 触发父组件事件
}

// 返回给模板使用
return { count, doubleCount, add }
}
}
</script>

2. 响应式数据定义

API 用途 注意点
ref 定义基础类型(Number/String/Boolean) 模板中自动解包(无需.value),JS中需.value
reactive 定义引用类型(Object/Array) 不能解构(解构会丢失响应式),返回代理对象
toRef 为reactive对象的单个属性创建ref 源属性不存在也不会报错,适合可选属性
toRefs 把reactive对象转为ref对象集合 解构reactive对象时保留响应式
shallowRef 浅响应式(仅.value本身响应式) 适合大型数据、无需深层响应式的场景
shallowReactive 浅响应式(仅第一层属性响应式) 同上

示例:reactive + toRefs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
import { reactive, toRefs } from 'vue'
export default {
setup() {
const user = reactive({
name: '张三',
age: 20
})

// 解构后保留响应式
const { name, age } = toRefs(user)

const updateName = () => {
user.name = '李四' // 或 name.value = '李四'
}

return { name, age, updateName }
}
}
</script>

3. 侦听器:watch & watchEffect

  • watch:显式指定侦听源,惰性执行(首次不触发),支持停止侦听、深度侦听、立即执行。
  • watchEffect:隐式侦听依赖,立即执行,自动收集响应式依赖,适合“副作用”处理(如请求、DOM操作)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script>
import { ref, watch, watchEffect } from 'vue'
export default {
setup() {
const count = ref(0)
const user = reactive({ name: '张三' })

// 1. watch侦听ref
watch(count, (newVal, oldVal) => {
console.log(`count从${oldVal}变到${newVal}`)
}, { immediate: true, deep: false }) // immediate:首次执行;deep:深度侦听

// 2. watch侦听reactive对象的单个属性
watch(() => user.name, (newName) => {
console.log(`姓名变为:${newName}`)
})

// 3. watchEffect(自动侦听用到的响应式数据)
const stopWatch = watchEffect(() => {
console.log(`count当前值:${count.value}`)
})

// 停止侦听
const stop = () => {
stopWatch()
}

return { count, user, stop }
}
}
</script>

4. 生命周期钩子(组合式API版)

Vue3的生命周期钩子需从vue导入,且不再有beforeCreate/created(直接写在setup中即可):

Options API Composition API(setup中) 执行时机
beforeCreate -(直接写setup) 组件创建前
created -(直接写setup) 组件创建后
beforeMount onBeforeMount 挂载前
mounted onMounted 挂载后(DOM可访问)
beforeUpdate onBeforeUpdate 响应式数据更新,DOM更新前
updated onUpdated DOM更新后
beforeUnmount onBeforeUnmount 组件卸载前
unmounted onUnmounted 组件卸载后(清理定时器/监听)

示例:生命周期使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
import { onMounted, onUnmounted, ref } from 'vue'
export default {
setup() {
const timer = ref(null)

onMounted(() => {
// 挂载后启动定时器
timer.value = setInterval(() => {
console.log('定时器运行中')
}, 1000)
})

onUnmounted(() => {
// 卸载前清理定时器
clearInterval(timer.value)
})
}
}
</script>

四、组件相关重点

1. 组件通信(Vue3主流方式)

方式 适用场景 示例要点
props + emit 父子组件通信 props定义验证,emit触发自定义事件
provide/inject 跨层级组件通信(祖孙) provide提供数据,inject注入数据,支持响应式
v-model升级 父子组件双向绑定 Vue3支持多个v-model,自定义绑定名
Pinia 全局状态管理 替代Vuex,更简洁,支持TS

示例:provide/inject(跨层级通信)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 父组件
<script>
import { provide, ref } from 'vue'
export default {
setup() {
const theme = ref('dark')
// 提供响应式数据
provide('theme', theme)
// 提供方法
provide('updateTheme', (newTheme) => {
theme.value = newTheme
})
}
}
</script>

// 孙组件
<script>
import { inject } from 'vue'
export default {
setup() {
// 注入数据
const theme = inject('theme', 'light') // 第二个参数是默认值
const updateTheme = inject('updateTheme')

return { theme, updateTheme }
}
}
</script>

示例:Vue3多v-model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 子组件
<template>
<input :value="name" @input="$emit('update:name', $event.target.value)">
<input :value="age" @input="$emit('update:age', $event.target.value)">
</template>
<script>
export default {
props: {
name: String,
age: Number
}
}
</script>

// 父组件
<template>
<Child v-model:name="username" v-model:age="userAge" />
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const username = ref('张三')
const userAge = ref(20)
return { username, userAge }
}
}
</script>

2. 插槽(Slots)

Vue3插槽用法和Vue2基本一致,但支持更灵活的写法:

  • 默认插槽:<slot>
  • 具名插槽:<slot name="footer">(父组件用v-slot:footer#footer
  • 作用域插槽:子组件向父组件传递数据,父组件接收并渲染。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 子组件
<template>
<div>
<!-- 作用域插槽:传递数据 -->
<slot name="item" :data="listItem" />
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const listItem = ref({ id: 1, text: '插槽数据' })
return { listItem }
}
}
</script>

// 父组件
<template>
<Child>
<template #item="slotProps">
<!-- 接收子组件传递的插槽数据 -->
<div>{{ slotProps.data.id }} - {{ slotProps.data.text }}</div>
</template>
</Child>
</template>

3. 新组件:Teleport & Suspense

  • Teleport:将组件渲染到指定DOM节点(如body),解决弹窗、模态框的层级问题。
  • Suspense:等待异步组件加载完成,显示占位内容(需配合异步组件使用)。

Teleport示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<button @click="showModal = true">打开弹窗</button>
<Teleport to="body">
<div v-if="showModal" class="modal">
弹窗内容(渲染到body下)
<button @click="showModal = false">关闭</button>
</div>
</Teleport>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const showModal = ref(false)
return { showModal }
}
}
</script>

五、状态管理:Pinia(替代Vuex)

Vue3官方推荐用Pinia替代Vuex,更简洁、支持TS、无嵌套模块:

1. 安装与创建Store

1
npm install pinia
1
2
3
4
5
6
7
8
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
app.use(createPinia())
app.mount('#app')

2. 定义Store

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// stores/counter.js
import { defineStore } from 'pinia'

// 第一个参数是store唯一标识
export const useCounterStore = defineStore('counter', {
// 状态(替代Vuex的state)
state: () => ({
count: 0
}),
// 计算属性(替代Vuex的getters)
getters: {
doubleCount: (state) => state.count * 2
},
// 方法(替代Vuex的mutations+actions,支持同步/异步)
actions: {
increment() {
this.count++
},
async incrementAsync() {
await new Promise(resolve => setTimeout(resolve, 1000))
this.count++
}
}
})

3. 组件中使用Store

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
import { useCounterStore } from '@/stores/counter'
export default {
setup() {
const counterStore = useCounterStore()

// 直接访问状态
console.log(counterStore.count)
// 访问getters
console.log(counterStore.doubleCount)
// 调用actions
counterStore.increment()
counterStore.incrementAsync()

return { counterStore }
}
}
</script>

六、路由:Vue Router 4(适配Vue3)

核心用法和Vue Router 3类似,但部分API调整:

1. 安装与配置

1
npm install vue-router@4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home.vue'

const routes = [
{ path: '/', component: Home },
{ path: '/about', component: () => import('@/views/About.vue') } // 懒加载
]

const router = createRouter({
history: createWebHistory(), // 替代Vue2的mode: 'history'
routes
})

export default router

2. 组件中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
import { useRouter, useRoute } from 'vue-router'
export default {
setup() {
const router = useRouter() // 替代this.$router
const route = useRoute() // 替代this.$route

// 编程式导航
const goToAbout = () => {
router.push('/about')
}

// 获取路由参数
console.log(route.params.id)

return { goToAbout }
}
}
</script>

七、TypeScript集成(Vue3+TS)

Vue3对TS的支持大幅提升,推荐用<script setup lang="ts">语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script setup lang="ts">
import { ref, reactive } from 'vue'

// 基础类型
const count = ref<number>(0)
// 接口定义
interface User {
name: string
age?: number
}
// 引用类型
const user = reactive<User>({ name: '张三' })
// props定义(需用defineProps)
const props = defineProps<{
initCount: number
title?: string
}>()
// emit定义(需用defineEmits)
const emit = defineEmits<{
(e: 'count-change', value: number): void
}>()
</script>

总结

  1. 核心核心:组合式API(setup、ref、reactive、watch、computed)是Vue3的灵魂,解决逻辑复用问题,需重点掌握。
  2. 响应式:Vue3用Proxy实现响应式,ref处理基础类型、reactive处理引用类型,toRefs解决解构丢失响应式问题。
  3. 生态适配:状态管理用Pinia(替代Vuex),路由用Vue Router 4,项目构建优先用Vite,TS集成大幅提升开发体验。
  4. 新特性:Teleport解决层级问题、Suspense处理异步加载、多v-model提升双向绑定灵活性,按需使用即可。

vue3重点
http://example.com/20260202-vue3重点/
作者
csorz
发布于
2026年2月2日
许可协议