昨天完成了表單常用的文字輸入框,感覺表單好像結束了呢!? 等等…還沒完呢! (我還有 25 天)
想想一個表單有一個以上的欄位要填寫,且有些欄位內容是固定的,如果需要使用者按照規定的格式填寫,難保會出現各種奇奇怪怪的寫法(x)
所以除了可以讓使用者自由輸入的輸入框以外,常見的還有下拉式選單 (select) ,下拉式選單能有效的提供使用者可用的選項,給予引導的效果,且在有大量資料需要呈現的情況下能讓畫面保持整潔喔~
一樣先思考 select 需要哪些狀態呢? 🤔
label
跟 placeholder
提示使用者輸入disabled
不可選取狀態<option>
選項可選與不可選狀態簡單介紹到這邊,讓我們開始實作吧!
開始實作會發現…喔不! 標籤並沒有像 標籤提供 placeholder
這個 attribute,別擔心我們可以把第一個 option
借來當作 placeholder
用用…
<script lang="ts" setup>
export interface SelectPropsType {
/** 預設內容文字 */
placeholder?: string
/** 標籤 */
label?: string
/** 標籤樣式 */
classLabel?: string
/** 輸入框樣式 */
classInput?: string
/** label for => select id */
name: string
/** v-modal */
modelValue: any
/** 錯誤訊息 */
error?: string
/** 是否不可選 */
disabled?: boolean
/** 是否複選 */
multiple?: boolean
/** 選項型別 */
options: Array<{
value: string
label: string
disabled?: boolean
}>
}
withDefaults(defineProps<SelectPropsType>(), {
label: '',
classLabel: '',
classInput: '',
name: '',
modelValue: '',
error: '',
description: '',
size: '',
options: () => [
{
value: '',
label: 'Select Option'
},
{
value: '',
label: 'Select Option2'
}
]
})
defineEmits(['update:modelValue'])
</script>
<template>
<div
class="fromGroup relative items-center"
:class="{'has-error': error}"
>
<label
class="input-label"
:for="name"
>
<span :class="classLabel">{{ label }}</span>
</label>
<div
class="relative"
>
<select
v-bind="$attrs"
:id="name"
:name="name"
:class="`${classInput} input-control`"
:value="modelValue"
:error="error"
:disabled="disabled"
:multiple="multiple"
@input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
>
<option
v-if="placeholder"
value=""
selected
>
{{ placeholder }}
</option>
<option
v-for="(item, index) in options"
:key="index"
:value="item.value"
:disabled="item.disabled"
>
{{ item.label }}
</option>
</select>
</div>
<span
v-if="error"
class="absolute -bottom-6 right-0 mt-2 text-red-500 block text-sm"
>{{ error }}</span>
</div>
</template>
<style>
select {
@apply ...
}
option {
@apply ...
}
</style>
defineModel
,可以試試看把它改成 defineModel
的模式呦完成之後的樣子~
<script lang="ts" setup>
const selectValue = ref('')
const options = [
{
value: '1',
label: '魚'
},
{
value: '2',
label: '金魚'
},
{
value: '3',
label: '大頭魚',
disabled: true
}
]
</script>
<template>
<div class="flex gap-x-4">
<Select :options="options" placeholder="- 請選擇魚 -" />
<Select :options="options" disabled placeholder="- 請選擇魚 -" />
<Select :options="options" disabled placeholder="- 請選擇魚 -" error="禁止撈魚"/>
</div>
</template>