Vue 3 的組合式 API
組合式 API 是 Vue 3 的核心特性之一,它允許開發者將組件的邏輯拆分為可復用的函數。組合式 API 的主要特點是
- 邏輯復用:將邏輯提取到獨立的函數中,方便在多個組件中復用。
- 組織清晰:將相關的邏輯分組,而不是將邏輯分散到 data、methods、computed 等選項中。
- 更接近函數式編程:通過函數組合的方式組織代碼。
在 Vue 3 中,自定義 Hooks 是通過組合式 API 的 ref、reactive、watch、computed 等函數實現的
- 基本的自定義 Hook
// useCounter.ts
import { ref } from 'vue';
export function useCounter(initialValue = 0) {const count = ref(initialValue);const increment = () => {count.value++;};const decrement = () => {count.value--;};return { count, increment, decrement };
}
在組件中使用:
<script setup>
import { useCounter } from './useCounter';const { count, increment, decrement } = useCounter(10);
</script><template><div><p>Count: {{ count }}</p><button @click="increment">Increment</button><button @click="decrement">Decrement</button></div>
</template>
- 路由跳轉
// useNavigation.ts
import { RouteLocationRaw } from 'vue-router'
import { useRouter } from 'vue-router'export function useNavigation() {const router = useRouter()// 基本跳轉const navigateTo = (to: RouteLocationRaw) => {return router.push(to)}// 替換當前路由const replaceRoute = (to: RouteLocationRaw) => {return router.replace(to)}// 返回上一頁const goBack = (delta = -1) => {router.go(delta)}// 前進const goForward = () => {router.go(1)}return {navigateTo,replaceRoute,goBack,goForward,router}
}
在組件中使用示例
<script setup lang="ts">
import { useNavigation } from '@/hooks/useNavigation'const {navigateTo,replaceRoute,goBack,goForward
} = useNavigation()// 路徑跳轉
const gotoHome = () => {navigateTo('/home')
}// 命名路由帶參數
const gotoDetail = (id: string) => {navigateTo({name: 'Detail',params: { id }})
}// 帶查詢參數
const gotoSearch = (keyword: string) => {navigateTo({path: '/search',query: { q: keyword }})
}// 替換當前路由
const replaceToLogin = () => {replaceRoute('/login')
}
</script><template><button @click="gotoHome">首頁</button><button @click="gotoDetail('123')">詳情頁</button><button @click="goBack">返回</button>
</template>
- 消息提示hooks
/useMessage.ts
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
import { useI18n } from './useI18n'
export const useMessage = () => {const { t } = useI18n()return {// 消息提示info(content: string) {ElMessage.info(content)},// 錯誤消息error(content: string) {ElMessage.error(content)},// 成功消息success(content: string) {ElMessage.success(content)},// 警告消息warning(content: string) {ElMessage.warning(content)},// 彈出提示alert(content: string) {ElMessageBox.alert(content, t('common.confirmTitle'))},// 錯誤提示alertError(content: string) {ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'error' })},// 成功提示alertSuccess(content: string) {ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'success' })},// 警告提示alertWarning(content: string) {ElMessageBox.alert(content, t('common.confirmTitle'), { type: 'warning' })},// 通知提示notify(content: string) {ElNotification.info(content)},// 錯誤通知notifyError(content: string) {ElNotification.error(content)},// 成功通知notifySuccess(content: string) {ElNotification.success(content)},// 警告通知notifyWarning(content: string) {ElNotification.warning(content)},// 確認窗體confirm(content: string, tip?: string) {return ElMessageBox.confirm(content, tip ? tip : t('common.confirmTitle'), {confirmButtonText: t('common.ok'),cancelButtonText: t('common.cancel'),type: 'warning'})},// 刪除窗體delConfirm(content?: string, tip?: string) {return ElMessageBox.confirm(content ? content : t('common.delMessage'),tip ? tip : t('common.confirmTitle'),{confirmButtonText: t('common.ok'),cancelButtonText: t('common.cancel'),type: 'warning'})},// 導出窗體exportConfirm(content?: string, tip?: string) {return ElMessageBox.confirm(content ? content : t('common.exportMessage'),tip ? tip : t('common.confirmTitle'),{confirmButtonText: t('common.ok'),cancelButtonText: t('common.cancel'),type: 'warning'})},// 提交內容prompt(content: string, tip: string) {return ElMessageBox.prompt(content, tip, {confirmButtonText: t('common.ok'),cancelButtonText: t('common.cancel'),type: 'warning'})}}
}