Vue 3 Composition API 详解
Vue 3 引入了 Composition API,这是一种全新的逻辑复用和代码组织方式,相比 Options API 更加灵活和可扩展。
什么是 Composition API?
Composition API 是基于函数的 API,允许我们将相关的逻辑组合在一起,而不是将逻辑分散在 data、methods、computed 等选项中。
Options API vs Composition API
export default { data() { return { count: 0, message: 'Hello Vue!' } }, methods: { increment() { this.count++ }, showMessage() { alert(this.message) } } }
import { ref } from 'vue'
export default { setup() { const count = ref(0) const message = ref('Hello Vue!') const increment = () => { count.value++ } const showMessage = () => { alert(message.value) } return { count, message, increment, showMessage } } }
|
核心概念
ref vs reactive
import { ref, reactive } from 'vue'
const count = ref(0) count.value++
const state = reactive({ count: 0, message: 'Hello' }) state.count++
|
computed
import { computed } from 'vue'
const doubleCount = computed(() => count.value * 2)
const fullName = computed(() => { return `${firstName.value} ${lastName.value}` })
|
watch
import { watch } from 'vue'
watch(count, (newVal, oldVal) => { console.log(`Count changed from ${oldVal} to ${newVal}`) })
watch([count, message], ([newCount, newMsg], [oldCount, oldMsg]) => { console.log(`Count: ${oldCount} -> ${newCount}`) console.log(`Message: ${oldMsg} -> ${newMsg}`) })
watch(state, (newVal, oldVal) => { console.log('State changed', newVal) }, { deep: true })
|
实战示例
表单处理
import { ref, reactive } from 'vue'
export default { setup() { const formData = reactive({ username: '', email: '', password: '' }) const errors = reactive({ username: '', email: '', password: '' }) const validate = () => { let valid = true if (!formData.username) { errors.username = 'Username is required' valid = false } if (!formData.email) { errors.email = 'Email is required' valid = false } if (!formData.password) { errors.password = 'Password is required' valid = false } return valid } const submit = () => { if (validate()) { console.log('Form submitted:', formData) } } return { formData, errors, submit } } }
|
列表管理
import { ref, onMounted } from 'vue'
export default { setup() { const items = ref([]) const loading = ref(false) const error = ref(null) const fetchItems = async () => { loading.value = true error.value = null try { const response = await fetch('https://api.example.com/items') const data = await response.json() items.value = data } catch (err) { error.value = err.message } finally { loading.value = false } } const addItem = (item) => { items.value.push(item) } const removeItem = (index) => { items.value.splice(index, 1) } onMounted(() => { fetchItems() }) return { items, loading, error, fetchItems, addItem, removeItem } } }
|
自定义 Hooks
import { ref, onMounted, onUnmounted } 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'
export default { setup() { const { x, y } = useMouse() return { x, y } } }
|
生命周期钩子
import { onMounted, onUpdated, onUnmounted } from 'vue'
export default { setup() { onMounted(() => { console.log('Component mounted') }) onUpdated(() => { console.log('Component updated') }) onUnmounted(() => { console.log('Component unmounted') }) } }
|
依赖注入
import { provide, inject } from 'vue'
const theme = ref('dark') provide('theme', theme)
const theme = inject('theme')
|
性能优化
import { shallowRef, markRaw } from 'vue'
const shallowObj = shallowRef({ count: 0 })
const nonReactiveObj = markRaw({ count: 0 })
const { count, message } = toRefs(state)
|
[!tip]
Composition API 特别适合复杂组件和逻辑复用,但简单组件可以直接使用 Options API。
总结
Composition API 提供了更灵活的代码组织方式,特别适合大型应用和复杂组件。它可以更好地实现逻辑复用,提高代码的可维护性。
参考资料