Vue 2.7 使用 Composition API
安装配置
1. 安装依赖
bash
npm install @vue/composition-api
# 或
yarn add @vue/composition-api
2. 注册插件
javascript
// main.js
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
基础用法
1. 基本结构
vue
<template>
<div>{{ count }}</div>
</template>
<script>
import { defineComponent, ref } from '@vue/composition-api'
export default defineComponent({
setup() {
const count = ref(0)
return {
count
}
}
})
</script>
2. 响应式引用
javascript
import { ref, reactive } from '@vue/composition-api'
// ref 用于基本类型
const count = ref(0)
console.log(count.value) // 获取值需要使用 .value
// reactive 用于对象
const state = reactive({
name: '张三',
age: 18
})
console.log(state.name) // 直接访问属性
3. 计算属性
javascript
import { ref, computed } from '@vue/composition-api'
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
// 可写的计算属性
const fullName = computed({
get: () => `${firstName.value} ${lastName.value}`,
set: (val) => {
[firstName.value, lastName.value] = val.split(' ')
}
})
4. 监听器
javascript
import { ref, watch, watchEffect } from '@vue/composition-api'
const count = ref(0)
// 基础监听
watch(count, (newVal, oldVal) => {
console.log('count changed:', newVal, oldVal)
})
// 监听多个数据源
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
console.log('values changed')
})
// 立即执行的监听器
watchEffect(() => {
console.log('count is:', count.value)
})
5. 生命周期钩子
javascript
import {
onMounted,
onBeforeMount,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
onErrorCaptured
} from '@vue/composition-api'
export default defineComponent({
setup() {
onBeforeMount(() => {
console.log('before mount')
})
onMounted(() => {
console.log('mounted')
})
// 其他生命周期钩子...
}
})
6. Props 和 Context
javascript
export default defineComponent({
props: {
title: String
},
setup(props, context) {
// props 是响应式的
console.log(props.title)
// context 包含 attrs, slots, emit
const { attrs, slots, emit } = context
// 触发事件
const handleClick = () => {
emit('custom-event', 'some data')
}
return {
handleClick
}
}
})
7. 提取复用逻辑(组合函数)
javascript
// useCounter.js
import { ref } from '@vue/composition-api'
export function useCounter(initialValue = 0) {
const count = ref(initialValue)
const increment = () => {
count.value++
}
const decrement = () => {
count.value--
}
return {
count,
increment,
decrement
}
}
// 使用组合函数
import { useCounter } from './useCounter'
export default defineComponent({
setup() {
const { count, increment, decrement } = useCounter(10)
return {
count,
increment,
decrement
}
}
})
8. 获取组件实例
javascript
import { getCurrentInstance } from '@vue/composition-api'
export default defineComponent({
setup() {
const { proxy } = getCurrentInstance()
// proxy 等同于 this
console.log(proxy.$router)
}
})
注意事项
setup
函数在组件创建之前被调用,此时组件实例还未创建setup
中不能使用this
ref
包装的值需要通过.value
访问- 返回的对象中的属性会暴露给模板使用
- 生命周期钩子需要在
setup
内同步调用
最佳实践
- 使用
defineComponent
获得更好的 TypeScript 支持 - 复杂的状态管理推荐使用
reactive
- 简单的值使用
ref
- 提取可复用的逻辑到组合函数中
- 保持
setup
函数简洁,将复杂逻辑拆分到组合函数
TypeScript 支持
typescript
import { defineComponent, PropType } from '@vue/composition-api'
interface User {
name: string
age: number
}
export default defineComponent({
props: {
user: {
type: Object as PropType<User>,
required: true
}
},
setup(props) {
// props.user 将有完整的类型提示
}
})