製作按鈕前要先規劃按鈕會有哪些狀態,與其在不同狀態下的樣式
例如:
step 1: 建立資料夾 components/global/ , Nuxt 預設 global
資料夾下的元件為全域
https://nuxt.com/docs/guide/directory-structure/components
step 2: 新增檔案 button.vue
到 global
資料夾下
props
方式來控制按鈕的狀態,並使用 withDefaults()
給予預設值btnClass
這個來控制 button
的顏色與樣式// button.vue
<script lang="ts" setup>
/** 定義按鈕型別 */
export interface ButtonPropsType {
/** 按鈕文字 */
text?: string
/** 是否 不可點擊 */
isDisabled?: boolean
/** 是否 載入狀態 */
isLoading?: boolean
/** 按鈕 外觀樣式 */
btnClass?: string
/** 按鈕 icon */
icon?: string
/** icon 樣式 */
iconClass?: string
}
withDefaults(defineProps<ButtonPropsType>(), {
text: '',
isDisabled: false,
isLoading: false,
btnClass: 'bg-primary-600 text-white',
icon: '',
iconClass: 'text-[20px]',
})
</script>
// button.vue
<template>
<button
:disabled="isDisabled"
class="btn"
:class="`
${isLoading ? 'pointer-events-none' : ''}
${isDisabled ? 'cursor-not-allowed pointer-events-none' : ''}
${btnClass}
`"
>
<template v-if="!isLoading && !$slots.default">
<span class="flex items-center">
<span
v-if="icon"
:class="`
${iconClass}
`"
>
<Icon :name="icon"/>
</span>
<span v-if="text">{{ text }}</span>
</span>
</template>
<template v-if="isLoading">
<Icon name="svg-spinners:tadpole" class="size-5 mr-2" />
Loading ...
</template>
<div v-if="$slots.default && !isLoading">
<slot />
</div>
</button>
</template>
<style scoped>
.btn {
/** 樣式設定 */
}
</style>
step 3: 最後整理一下,在 pages/
下新建立一個 button
頁面來呈現剛剛做好的 button
元件 ~
// pages/button.vue
<template>
<div class="flex items-center gap-x-2">
<Button text="primary" isLoading />
<Button text="primary" isDisabled />
<Button text="Reward" icon="mingcute:award-fill" iconClass="text-yellow-500 mr-2" />
<Button text="primary" />
</div>
</template>
最後完成的樣子就是這樣囉~