Admin 元件
Input
文字輸入欄位。可搭配清除、密碼切換、字數限制等子組件。
安裝
Terminal
pnpm dlx shadcn-vue add @admin/inputimport { AdminInput, AdminInputClear, AdminInputPasswordToggle, AdminInputWordLimit,} from '@/components/admin/input'用法
<script setup lang="ts">import { ref } from 'vue'import { AdminInput } from '@/components/admin/input'const value = ref<string | number>('')</script><template> <admin-input v-model="value" class="w-64" placeholder="Type here" /></template>場景
可清除內容
輸入框在有值時會顯示清除按鈕。
<script setup lang="ts">import { ref } from 'vue'import { AdminInput, AdminInputClear } from '@/components/admin/input'const value = ref<string | number>('Hello')</script><template> <admin-input v-model="value" class="w-64" placeholder="輸入關鍵字"> <template #suffix> <admin-input-clear /> </template> </admin-input></template>密碼欄位與顯示切換
<script setup lang="ts">import { ref } from 'vue'import { AdminInput, AdminInputPasswordToggle } from '@/components/admin/input'const password = ref<string | number>('secret-123')</script><template> <admin-input v-model="password" class="w-64" placeholder="密碼" type="password"> <template #suffix> <admin-input-password-toggle /> </template> </admin-input></template>錯誤狀態
<script setup lang="ts">import { ref } from 'vue'import { AdminInput } from '@/components/admin/input'const value = ref<string | number>('錯誤內容')</script><template> <admin-input v-model="value" class="w-64" placeholder="Type here" is-error /></template>Type-safe 封裝
AdminInput 採原生 input 封裝,modelValue 為 string | number,不會依 type 在 compile-time 與 v-model 型別對齊。
開啟 strictVModel 或 strictTemplates 時,若以更嚴的型別(例如 number | null)綁定,容易出現型別錯誤。這屬原生 input 的型別行為,而非元件缺漏。
若需要讓 type 與 v-model 型別對齊,可自行封裝。
範例:
TypedAdminInput.vue
<script setup lang="ts" generic="TInputType extends InputTypeHTMLAttribute">import type { InputTypeHTMLAttribute } from 'vue'import type { AdminInputEmits, AdminInputProps, AdminInputSlots } from '@/components/admin/input'import { reactiveOmit } from '@vueuse/core'import { useForwardPropsEmits } from 'reka-ui'import { computed } from 'vue'import { AdminInput } from '@/components/admin/input'type TModelValue = [TInputType] extends ['number'] ? number | null : stringdefineOptions({ name: 'typed-admin-input'})const props = defineProps< Omit<AdminInputProps, 'modelValue' | 'defaultValue' | 'type'> & { type?: TInputType modelValue?: TModelValue defaultValue?: TModelValue }>()const emits = defineEmits< Omit<AdminInputEmits, 'update:modelValue'> & { 'update:modelValue': [value: TModelValue] }>()const slots = defineSlots<AdminInputSlots>()const delegatedProps = reactiveOmit(props, 'modelValue')const forwardedAll = useForwardPropsEmits(delegatedProps, emits)const forwarded = computed(() => { const { 'onUpdate:modelValue': _, ...rest } = forwardedAll.value return rest})const innerValue = computed<string | number>({ get() { return props.modelValue ?? '' }, set(value) { if (props.type === 'number' && value === '') { emits('update:modelValue', null as TModelValue) return } emits('update:modelValue', value as TModelValue) }})</script><template> <admin-input v-bind="forwarded" v-model="innerValue"> <template v-for="(_, name) in slots" #[name]> <slot :name="name"></slot> </template> </admin-input></template>number | null 需處理清空
若型別為 number | null,runtime 仍須處理清空:原生 type="number" 清空時值會變成空字串 '',需轉成 null,型別才與實際行為一致。
需開啟 strictVModel
型別檢查需開啟 strictVModel(若已開啟 strictTemplates 則已包含)。設定見 Type-safe。下列同時含合法綁定與刻意錯誤綁定;錯誤處以 @vue-expect-error 標示。
<script setup lang="ts">import { ref } from 'vue'import TypedAdminInput from './typed-admin-input-demo.vue'const numberAndNullValue = ref<number | null>(null)const stringValue = ref('')</script><template> <div class="flex w-full max-w-md flex-col gap-6"> <!-- number | null --> <typed-admin-input v-model="numberAndNullValue" type="number" /> <!-- @vue-expect-error type 設定成 number,但 value 給 string 就會報錯 --> <typed-admin-input v-model="stringValue" type="number" /> <!-- string --> <typed-admin-input v-model="stringValue" /> <!-- @vue-expect-error type 設定成非 number,但 value 給 number 就會報錯 --> <typed-admin-input v-model="numberAndNullValue" type="text" /> </div></template>API 參考
組成
<template> <admin-input v-model="value" placeholder="輸入文字"> <template #suffix> <admin-input-clear /> </template> </admin-input></template>admin-input
Props
| 名稱 | 型別 | 預設值 | 說明 |
|---|---|---|---|
defaultValue | string | number | undefined | — | 初始值(非控制模式) |
modelValue | string | number | undefined | — | 受控值,以 `v-model` 綁定 |
placeholder | string | undefined | — | 預設提示文字 |
disabled | boolean | undefined | — | 設為 `true` 時禁用輸入並套用視覺停用樣式 |
readonly | boolean | undefined | — | 設為 `true` 時禁止編輯文字,但仍允許 focus 與 selection |
maxlength | number | undefined | — | 限制最大字元數(並由 `admin-input-word-limit` 顯示計數) |
class | ClassValue | — | 根元素之自訂 class |
type | InputTypeHTMLAttribute | undefined | "text" | HTML input type(如 `text`、`password`、`number`) |
isError | boolean | undefined | — | 設為 `true` 時套用錯誤狀態樣式與 `aria-invalid` |
id | string | undefined | — | 透傳至內層 `input` 之 `id`;純透傳,未提供時不自動生成 |
name | string | undefined | — | 透傳至內層 `input` 之 `name`,供原生表單提交使用 |
Events
| 名稱 | Payload | 說明 |
|---|---|---|
blur | FocusEvent | 內層 `input` 失焦時轉發之原生事件 |
change | Event | 內層 `input` 觸發原生 `change`(值變更並 commit)時轉發之原生事件 |
input | Event | 內層 `input` 觸發原生 `input`(每次輸入)時轉發之原生事件 |
update:modelValue | string | number | modelValue 更新時觸發 |
Slots
| 名稱 | Bindings | 說明 |
|---|---|---|
default | any | 預設 slot |
prefix | any | 輸入框前綴 slot,常用於放置 icon |
suffix | any | 輸入框後綴 slot,常用於放置 icon、清除按鈕、字數計數 |
Expose
| 名稱 | 簽名 | 說明 |
|---|---|---|
input | HTMLInputElement | null | 內部原生 input 元素之 template ref,可用於程式化 focus / blur / select 等操作 |
admin-input-clear
Props
| 名稱 | 型別 | 預設值 | 說明 |
|---|---|---|---|
class | unknown | — | — |
Events
| 名稱 | Payload | 說明 |
|---|---|---|
clear | — | 點擊清除按鈕、值已清空後觸發 |
Slots
| 名稱 | Bindings | 說明 |
|---|---|---|
default | {} | — |
admin-input-password-toggle
Props
| 名稱 | 型別 | 預設值 | 說明 |
|---|---|---|---|
class | unknown | — | — |
admin-input-word-limit
Props
| 名稱 | 型別 | 預設值 | 說明 |
|---|---|---|---|
class | unknown | — | — |