一、组件通信妙招
1. 深层透传属性
<!-- Parent.vue -->
<Child v-bind="$attrs" />
<!-- Child.vue -->
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
console.log(attrs.class) // 获取透传的class
</script>
场景:跨多层组件传递属性时避免逐层声明
亮点:自动继承未声明props,保持组件纯净
2. 依赖注入类型安全
// types.ts
interface UserInfo {
name: string
age: number
}
// Parent.vue
provide<UserInfo>('userInfo', { name: 'Alice', age: 28 })
// Child.vue
const user = inject<UserInfo>('userInfo')!
优势:配合TypeScript实现类型安全的provide/inject
二、性能优化技巧
1. 列表渲染优化
<template>
<div v-for="item in list" :key="item.id" v-memo="[item.id]">
{{ item.content }}
</div>
</template>
效果:当item.id不变时跳过虚拟DOM比对
适用:大型静态列表或复杂组件
2. 组件懒加载
<script setup>
import { defineAsyncComponent } from 'vue'
const HeavyComponent = defineAsyncComponent(() =>
import('./HeavyComponent.vue'), {
loadingComponent: LoadingSpinner,
delay: 200 // 延迟显示loading
}
)
</script>
优势:按需加载减少首包体积
三、组合式API进阶
1. 智能Ref类型
import { ref } from 'vue'
// 自动推断类型为Ref<number>
const count = ref(0)
// 显式声明复杂类型
const user = ref<{ name?: string }>({})
亮点:类型提示 + 响应式统一管理
2. 状态共享Hook
// useCounter.ts
export default function useCounter(initial = 0) {
const count = ref(initial)
const increment = () => count.value++
const decrement = () => count.value--
return {
count,
increment,
decrement
}
}
// 组件中使用
const { count, increment } = useCounter()
优势:逻辑复用且保持响应式隔离
四、模板黑科技
1. 动态组件缓存
<template>
<component :is="currentComponent" v-bind="props" />
</template>
<script setup>
import { shallowRef } from 'vue'
const components = {
Home: defineAsyncComponent(() => import('./Home.vue')),
Profile: defineAsyncComponent(() => import('./Profile.vue'))
}
const currentComponent = shallowRef(components.Home)
</script>
技巧:使用shallowRef避免不必要的响应式开销
2. 指令复用策略
<template>
<div v-auth:edit @click="handleEdit">编辑</div>
</template>
<script setup>
// 权限指令
const vAuth = {
mounted(el, binding) {
const hasPermission = checkAuth(binding.arg)
if (!hasPermission) el.style.display = 'none'
}
}
</script>
场景:统一权限控制逻辑
五、状态管理优化
1. Pinia自动持久化
// store/user.ts
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
token: localStorage.getItem('token') || ''
}),
persist: {
paths: ['token'],
storage: sessionStorage // 按需切换存储方式
}
})
效果:状态关闭浏览器后依然保留
2. Getters动态计算
// store/product.ts
export const useProductStore = defineStore('product', {
state: () => ({
items: [] as Product[],
filter: ''
}),
getters: {
filteredItems: (state) => {
return state.items.filter(item =>
item.name.includes(state.filter)
}
}
})
优势:带缓存的计算属性式获取
六、调试技巧
1. 组件注入调试信息
<script setup>
import { useDevtools } from '@vue/devtools'
if (process.env.NODE_ENV === 'development') {
const devtools = useDevtools()
devtools.inspectState('Custom State', {
debugValue: 'Vue3 rocks!'
})
}
</script>
效果:在Vue Devtools中显示自定义调试信息
2. 性能标记
<script setup>
import { startMeasure, stopMeasure } from 'vue-performance-measure'
onMounted(() => {
startMeasure('ComponentInit')
// 初始化逻辑...
stopMeasure('ComponentInit')
})
</script>
输出:在控制台查看组件初始化耗时
七、工程化实践
1. 自动导入组件
// vite.config.js
import Components from 'unplugin-vue-components/vite'
export default defineConfig({
plugins: [
Components({
dts: true, // 生成类型声明
resolvers: [
// 自动导入Element Plus组件
ElementPlusResolver()
]
})
]
})
优势:无需手动import组件
2. 路由元信息验证
// router.ts
import { defineRouteMeta } from 'vue-router/auto'
defineRouteMeta({
auth: true,
transition: 'fade'
})
// 路由守卫中访问
router.beforeEach((to) => {
if (to.meta.auth && !isLoggedIn()) return '/login'
})
亮点:类型安全的元数据管理