Vue3 知识点总结
1. 核心概念
1.1 Composition API
1.1.1 setup 函数
setup是Vue3中的新的配置项,是组件内使用Composition API的入口 在setup中定义的变量和方法需要return才能在模板中使用 setup执行时机在beforeCreate之前,this不可用
export default {
setup ( ) {
const count = ref ( 0 )
const increment = ( ) => count. value++
return {
count,
increment
}
}
}
1.1.2 响应式API
ref
用于基本类型的响应式 在setup中需要.value访问 在模板中自动解包
const count = ref ( 0 )
console. log ( count. value)
reactive
const state = reactive ( {
count: 0 ,
list: [ ]
} )
toRef 和 toRefs
toRef: 为源响应式对象上的属性新建ref toRefs: 将响应式对象转换为普通对象,其中每个属性都是ref
const state = reactive ( {
foo: 1 ,
bar: 2
} )
const fooRef = toRef ( state, 'foo' )
const stateRefs = toRefs ( state)
1.2 生命周期钩子
setup(): 组件创建前执行 onBeforeMount(): 组件挂载前 onMounted(): 组件挂载后 onBeforeUpdate(): 组件更新前 onUpdated(): 组件更新后 onBeforeUnmount(): 组件卸载前 onUnmounted(): 组件卸载后
import { onMounted } from 'vue'
export default {
setup ( ) {
onMounted ( ( ) => {
console. log ( '组件已挂载' )
} )
}
}
1.3 依赖注入
provide/inject
provide ( 'key' , value)
const value = inject ( 'key' )
2. 新特性
2.1 Teleport
将组件内容渲染到指定DOM节点 常用于模态框、弹出层等
<teleport to="body">
<div class="modal">
<!-- 模态框内容 -->
</div>
</teleport>
2.2 Fragments
<template>
<header>...</header>
<main>...</main>
<footer>...</footer>
</template>
2.3 Suspense
<suspense>
<template #default>
<async-component />
</template>
<template #fallback>
<loading-component />
</template>
</suspense>
3. 状态管理
3.1 Pinia
Vue3推荐的状态管理方案 支持TypeScript 轻量级、模块化
import { defineStore } from 'pinia'
export const useCounterStore = defineStore ( 'counter' , {
state : ( ) => ( {
count: 0
} ) ,
actions: {
increment ( ) {
this . count++
}
}
} )
4. 性能优化
4.1 静态提升
4.2 Patch Flag
4.3 Tree Shaking
5. TypeScript支持
5.1 类型定义
interface User {
id: number
name: string
}
const user = ref < User> ( { id: 1 , name: 'Tom' } )
5.2 组件Props类型
defineProps < {
title: string
count: number
} > ( )
6. 工程化实践
6.1 Vite
更快的开发服务器启动 更快的模块热更新 优化的构建输出
6.2 单文件组件
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
6.3 组件设计原则
单一职责 可复用性 Props向下,Events向上 组件通信规范
7. 最佳实践
7.1 代码组织
使用组合式函数(Composables) 逻辑复用和抽象 目录结构规范
7.2 性能考虑
合理使用computed和watch 避免不必要的组件渲染 使用v-show代替v-if(频繁切换)
7.3 错误处理
7.4 自定义指令
app. directive ( 'debounce' , {
mounted ( el, binding ) {
const delay = binding. value || 300
let timer = null
el. addEventListener ( 'click' , ( ) => {
if ( timer) clearTimeout ( timer)
timer = setTimeout ( ( ) => {
binding. value ( )
} , delay)
} )
}
} )
7.5 动画与过渡
v-enter-from/v-leave-to transition组件 transition-group列表过渡
<template>
<transition name="fade">
<div v-if="show">Content</div>
</transition>
</template>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
7.6 组合式函数(Composables)
import { ref, onMounted } from 'vue'
export function useCounter ( initialValue = 0 ) {
const count = ref ( initialValue)
const increment = ( ) => count. value++
const decrement = ( ) => count. value--
onMounted ( ( ) => {
console. log ( 'Counter mounted' )
} )
return {
count,
increment,
decrement
}
}
const { count, increment } = useCounter ( )
7.7 与其他技术栈集成
7.7.1 Vue3 + TypeScript
interface Props {
message: string
count? : number
}
defineProps < Props> ( )
interface UseUserReturn {
user: Ref< User | null >
loading: Ref< boolean >
error: Ref< Error | null >
fetchUser : ( id: number ) => Promise < void >
}
function useUser ( ) : UseUserReturn {
}
7.7.2 Vue3 + Vite + TailwindCSS
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import tailwindcss from 'tailwindcss'
export default defineConfig ( {
plugins: [ vue ( ) ] ,
css: {
postcss: {
plugins: [ tailwindcss]
}
}
} )
7.7.3 Vue3 + Jest
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'
test ( 'increments value on click' , async ( ) => {
const wrapper = mount ( Counter)
await wrapper. find ( 'button' ) . trigger ( 'click' )
expect ( wrapper. text ( ) ) . toContain ( '1' )
} )
8. 高级组件模式
8.1 动态组件
<template>
<component :is="currentComponent" v-bind="props" />
</template>
<script setup>
import { shallowRef } from 'vue'
const currentComponent = shallowRef(null)
const props = ref({})
// 异步加载组件
async function loadComponent(name) {
const component = await import(`./components/${name}.vue`)
currentComponent.value = component.default
}
</script>
8.2 递归组件
<!-- TreeNode.vue -->
<template>
<div class="tree-node">
<div @click="toggle">{{ node.label }}</div>
<div v-if="isExpanded && node.children" class="children">
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child"
/>
</div>
</div>
</template>
<script setup>
const props = defineProps(['node'])
const isExpanded = ref(false)
const toggle = () => isExpanded.value = !isExpanded.value
</script>
8.3 高阶组件(HOC)
import { h, defineComponent } from 'vue'
export function withLoading ( WrappedComponent) {
return defineComponent ( {
props: [ 'loading' , ... WrappedComponent. props] ,
setup ( props, { attrs, slots } ) {
return ( ) => props. loading
? h ( 'div' , 'Loading...' )
: h ( WrappedComponent, { ... attrs } , slots)
}
} )
}
9. 性能优化最佳实践
9.1 大列表优化
<script setup>
import { useVirtualList } from '@vueuse/core'
const list = ref(Array.from({ length: 10000 }, (_, i) => ({ id: i, text: `Item ${i}` })))
const { list: virtualList, containerProps, wrapperProps } = useVirtualList(list, {
itemHeight: 40,
overscan: 10
})
</script>
<template>
<div v-bind="containerProps" class="container">
<div v-bind="wrapperProps">
<div v-for="item in virtualList" :key="item.id" class="item">
{{ item.text }}
</div>
</div>
</div>
</template>
9.2 组件懒加载
const routes = [
{
path: '/dashboard' ,
component : ( ) => import ( './views/Dashboard.vue' )
}
]
const MyComponent = defineAsyncComponent ( ( ) =>
import ( './components/MyComponent.vue' )
)
9.3 计算属性缓存
const expensiveComputed = computed ( ( ) => {
return list. value. filter ( item => {
return complexProcess ( item)
} )
} )
const fullName = computed ( {
get ( ) {
return ` ${ firstName. value} ${ lastName. value} `
} ,
set ( newValue) {
[ firstName. value, lastName. value] = newValue. split ( ' ' )
}
} )
10. 与Vue2的主要区别
10.1 核心架构
使用Proxy代替Object.defineProperty实现响应式 重写虚拟DOM实现,性能提升100% 模板编译优化,支持静态提升 更好的TypeScript支持,内置类型声明
10.2 API差异
Composition API vs Options API 新的生命周期钩子 移除filter和
o
n
、
on、
o n 、 off等API setup函数替代beforeCreate和created
10.3 模板语法
v-model的使用变化(modelValue + update:modelValue) 支持多个v-model绑定 Teleport、Suspense等新特性 片段(Fragments)支持多根节点
10.4 响应式系统
ref和reactive的显式声明 更好的响应式解构支持(toRefs) 响应式数据的调试能力增强 更细粒度的响应式控制