1. Composition API 优势
逻辑组织更清晰
javascript
// Vue 2 Options API
export default {
data() {
return {
userList: [],
loading: false
}
},
methods: {
fetchUsers() { /* ... */ }
},
computed: {
activeUsers() { /* ... */ }
}
}
// Vue 3 Composition API
import { ref, computed, onMounted } from 'vue'
export default {
setup() {
const userList = ref([])
const loading = ref(false)
const activeUsers = computed(() => {
return userList.value.filter(user => user.active)
})
const fetchUsers = async () => {
// ...
}
onMounted(() => {
fetchUsers()
})
return {
userList,
loading,
activeUsers,
fetchUsers
}
}
}
逻辑复用更方便
javascript
import { ref, reactive } from 'vue'
export function useAuth() {
const user = ref(null)
const isAuthenticated = computed(() => !!user.value)
const login = async (credentials) => {
// 登录逻辑
}
const logout = () => {
user.value = null
}
return {
user,
isAuthenticated,
login,
logout
}
}
// 在组件中使用
export default {
setup() {
const { user, isAuthenticated, login, logout } = useAuth()
return {
user,
isAuthenticated,
login,
logout
}
}
}
2. 性能优化
更好的 Tree-shaking
javascript
// 只引入需要的 API import { ref, computed, watch } from 'vue'
更高效的响应式系统
php
javascript
// Vue 3 Proxy-based 响应式
const state = reactive({
user: {
profile: {
name: 'John'
}
}
})
// Vue 2 Object.defineProperty
// 需要递归遍历所有属性
3. TypeScript 支持
typescript
typescript
import { defineComponent, ref, PropType } from 'vue'
interface User {
id: number
name: string
email: string
}
export default defineComponent({
props: {
users: {
type: Array as PropType<User[]>,
required: true
}
},
setup(props) {
const selectedUser = ref<User | null>(null)
const selectUser = (user: User) => {
selectedUser.value = user
}
return {
selectedUser,
selectUser
}
}
})
4. Teleport 组件
xml
vue
<template>
<div class="modal">
<teleport to="body">
<div class="modal-overlay" v-if="visible">
<div class="modal-content">
<slot></slot>
</div>
</div>
</teleport>
</div>
</template>
5. Suspense 组件
xml
vue
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>
6. 多个 v-model 支持
xml
vue
<template>
<MyComponent
v-model:title="pageTitle"
v-model:content="pageContent"
/>
</template>
<!-- MyComponent.vue -->
<template>
<input v-model="title" />
<textarea v-model="content" />
</template>
<script>
export default {
props: ['title', 'content'],
emits: ['update:title', 'update:content']
}
</script>
7. Fragment 支持
xml
vue
<template>
<!-- 不再需要单一根元素 -->
<header>...</header>
<main>...</main>
<footer>...</footer>
</template>
8. 实用技巧
使用 watchEffect 自动追踪依赖
csharp
javascript
import { ref, watchEffect } from 'vue'
const userId = ref(1)
const user = ref(null)
watchEffect(async () => {
if (userId.value) {
user.value = await fetchUser(userId.value)
}
})
使用 provide/inject 进行依赖注入
javascript
javascript
// 父组件
import { provide, ref } from 'vue'
export default {
setup() {
const theme = ref('dark')
provide('theme', theme)
}
}
// 子组件
import { inject } from 'vue'
export default {
setup() {
const theme = inject('theme')
return { theme }
}
}
使用自定义指令
javascript
javascript
const MyDirective = {
mounted(el, binding) {
el.focus()
}
}
export default {
directives: {
focus: MyDirective
}
}
9. 常见陷阱与解决方案
响应式解构问题
scss
javascript
// ❌ 错误:失去响应性
const { count, double } = useCounter()
// ✅ 正确:保持响应性
const counter = useCounter()
const { count, double } = toRefs(counter)
// 或者使用 reactive
const state = reactive(useCounter())
异步组件加载
javascript
javascript
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent({
loader: () => import('./MyComponent.vue'),
loadingComponent: LoadingComponent,
errorComponent: ErrorComponent,
delay: 200,
timeout: 3000
})
10. 最佳实践
- 合理使用 Composition API:不是所有情况都需要使用,简单组件用 Options API 也很好
- 组件拆分:保持组件小巧,单一职责
- 状态管理:复杂应用使用 Pinia 或 Vuex
- 性能优化 :合理使用
v-memo
、v-once
等优化手段 - 类型安全:尽可能使用 TypeScript 提高代码质量
Vue 3 带来了很多现代化的特性,让开发体验更加流畅,但也要根据项目实际情况选择合适的特性使用。