Vue3在实际项目开发中,高频使用到的相关的内容。
一、Composition API(核心范式)
替代 Options API 的逻辑组织方式,更适合复杂组件和逻辑复用。
<script setup>
import { ref, computed, onMounted } from 'vue'
// 1. 响应式数据
const count = ref(0) // 基本类型
const user = ref({ name: 'Alice', age: 30 }) // 对象类型
// 2. 计算属性
const doubledCount = computed(() => count.value * 2)
// 3. 方法
const increment = () => {
count.value++
user.value.age++ // 自动触发更新
}
// 4. 生命周期
onMounted(() => {
console.log('组件挂载完成,初始计数:', count.value)
})
// 5. 暴露给模板
defineExpose({ increment }) // 父组件可通过ref调用
</script>
<template>
<button @click="increment">
{{ count }} - 双倍: {{ doubledCount }}
</button>
<p>{{ user.name }} 年龄: {{ user.age }}</p>
</template>
二、响应式进阶
1. ref vs reactive
// ref:通用类型,通过.value访问
const num = ref(42)
// reactive:仅对象类型(无.value)
const state = reactive({
items: [],
loading: false
})
// 解构响应式对象(保持响应性)
import { toRefs } from 'vue'
const { items, loading } = toRefs(state)
2. 深度监听(watchEffect 和 watch)
// 自动依赖跟踪
watchEffect(() => {
console.log('计数变化:', count.value)
})
// 精确监听
watch(
() => user.value.age,
(newAge, oldAge) => {
alert(`年龄从 ${oldAge} 变为 ${newAge}`)
},
{ deep: true } // 深度监听对象内部变化
)
三、组件通信
1. Props + Emits
<!-- Parent.vue -->
<Child :title="pageTitle" @update-title="handleUpdate" />
<!-- Child.vue -->
<script setup>
defineProps(['title'])
const emit = defineEmits(['update-title'])
const changeTitle = () => {
emit('update-title', '新标题-' + Date.now())
}
</script>
2. 依赖注入(Provide/Inject)
// 祖先组件
import { provide, ref } from 'vue'
const globalConfig = ref({ theme: 'dark' })
provide('appConfig', globalConfig)
// 后代组件
import { inject } from 'vue'
const config = inject('appConfig')
console.log(config.value.theme) // 'dark'
四、状态管理(Pinia 示例)
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++
}
},
getters: {
doubleCount: (state) => state.count * 2
}
})
// 组件中使用
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
// 读取状态
console.log(store.doubleCount)
// 修改状态
store.increment()
// 订阅变化
store.$subscribe((mutation) => {
console.log('状态变化:', mutation)
})
五、路由管理(Vue Router 4)
// router.js
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/user/:id',
component: () => import('./views/User.vue'),
props: true // 自动将路由参数转为props
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// 组件内获取路由信息
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
console.log('用户ID:', route.params.id)
const router = useRouter()
router.push({ name: 'home' })
六、异步处理最佳实践
<script setup>
import { ref } from 'vue'
const data = ref(null)
const error = ref(null)
const loading = ref(false)
const fetchData = async () => {
try {
loading.value = true
const res = await fetch('https://api.example.com/data')
data.value = await res.json()
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
}
</script>
<template>
<div v-if="loading">加载中...</div>
<div v-else-if="error">错误: {{ error }}</div>
<div v-else>{{ data }}</div>
</template>
七、组件复用(Composables)
// composables/useMouse.js
import { onMounted, onUnmounted, ref } from 'vue'
export function useMouse() {
const x = ref(0)
const y = ref(0)
const update = e => {
x.value = e.pageX
y.value = e.pageY
}
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
return { x, y }
}
// 组件中使用
import { useMouse } from './useMouse'
const { x, y } = useMouse()
八、性能优化技巧
<template>
<!-- 1. v-once 静态内容优化 -->
<div v-once>{{ staticText }}</div>
<!-- 2. 虚拟滚动长列表 -->
<RecycleScroller
v-slot="{ item }"
:items="bigList"
item-size="50"
class="scroller"
>
{{ item.name }}
</RecycleScroller>
<!-- 3. KeepAlive 缓存组件 -->
<KeepAlive include="TabComponent">
<component :is="currentComponent" />
</KeepAlive>
</template>
<script>
// 4. 组件懒加载
import { defineAsyncComponent } from 'vue'
const HeavyComponent = defineAsyncComponent(() =>
import('./HeavyComponent.vue')
)
</script>
九、TypeScript 集成
<script setup lang="ts">
interface User {
id: number
name: string
email?: string
}
// 类型化props
const props = defineProps<{
title: string
user: User
}>()
// 类型化emits
const emit = defineEmits<{
(e: 'update', payload: User): void
}>()
</script>
十、调试技巧
// 1. 自定义 Ref 调试器
import { ref } from 'vue'
const debugRef = (target, label = 'Debug Ref') => {
return ref({
get value() {
console.log(`${label} Get:`, target.value)
return target.value
},
set value(newVal) {
console.log(`${label} Set:`, newVal)
target.value = newVal
}
})
}
// 2. Vue Devtools 时间线记录
import { nextTick } from 'vue'
nextTick(() => {
performance.mark('custom-event-end')
})
这些功能涵盖了 Vue3 开发的 90% 日常使用场景。最佳实践建议:
- 中小项目优先使用 Composition API + Provide/Inject
- 复杂状态使用 Pinia 替代 Vuex
- 逻辑复用使用 Composables
- 性能敏感场景使用
<script setup>语法 - 类型安全优先使用 TypeScript
新项目推荐技术栈:
- 构建工具:Vite
- 状态管理:Pinia
- 路由:Vue Router 4
- UI 库:Element Plus / Naive UI
- 代码规范:ESLint + Prettier