你系统、详细地整理Vue3的核心重点知识,覆盖从基础到进阶的关键内容,方便梳理学习脉络和掌握核心用法。
一、Vue3核心升级与优势
先明确Vue3相比Vue2的核心变化,这是理解后续知识点的基础:
- 架构重构:基于Monorepo管理源码,拆分为
vue-core、compiler、reactivity等独立包,体积更小(按需引入)、可维护性更高。
- 组合式API(Composition API):替代Options API的部分场景,解决大型组件中逻辑复用和代码分散的问题。
- 响应式系统重构:用
Proxy替代Vue2的Object.defineProperty,支持数组、对象动态新增属性、Map/Set等复杂数据类型的响应式。
- 更好的TypeScript支持:源码全部用TS重写,开发者编写代码时能获得更完善的类型提示。
- 性能优化:编译阶段优化(静态节点提升、PatchFlags)、虚拟DOM重写,渲染性能提升约55%,内存占用减少约50%。
- 新特性:Teleport(瞬移组件)、Suspense(异步加载占位)、多根节点组件、Vite适配等。
二、Vue3基础核心
1. 项目创建(两种主流方式)
Vue3推荐用Vite(极速冷启动),也兼容Vue CLI:
1 2 3 4 5 6 7 8 9
| npm create vite@latest my-vue3-project -- --template vue cd my-vue3-project npm install npm run dev
vue create my-vue3-project
|
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
| import { createApp } from 'vue' import App from './App.vue'
const app = createApp(App)
app.config.errorHandler = (err) => { console.error(err) }
app.component('GlobalComp', GlobalComp).directive('focus', focusDirective) app.mount('#app')
|
三、核心重点:组合式API(Composition API)
这是Vue3最核心的知识点,解决Options API“逻辑碎片化”问题,建议优先掌握:
1. setup函数(组合式API的入口)
- 执行时机:组件创建前(beforeCreate之前),此时
this为undefined。
- 入参:
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 2 3 4 5 6 7 8
| 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
| import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', { state: () => ({ count: 0 }), getters: { doubleCount: (state) => state.count * 2 }, 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
| 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(), 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>
|
总结
- 核心核心:组合式API(setup、ref、reactive、watch、computed)是Vue3的灵魂,解决逻辑复用问题,需重点掌握。
- 响应式:Vue3用Proxy实现响应式,
ref处理基础类型、reactive处理引用类型,toRefs解决解构丢失响应式问题。
- 生态适配:状态管理用Pinia(替代Vuex),路由用Vue Router 4,项目构建优先用Vite,TS集成大幅提升开发体验。
- 新特性:Teleport解决层级问题、Suspense处理异步加载、多v-model提升双向绑定灵活性,按需使用即可。