Admin 元件

Input

參考
文字輸入欄位。可搭配清除、密碼切換、字數限制等子組件。

安裝

Terminal
pnpm dlx shadcn-vue add @admin/input
import {  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 : string​defineOptions({  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

名稱型別預設值說明
defaultValuestring | number | undefined—初始值(非控制模式)
modelValuestring | number | undefined—受控值,以 `v-model` 綁定
placeholderstring | undefined—預設提示文字
disabledboolean | undefined—設為 `true` 時禁用輸入並套用視覺停用樣式
readonlyboolean | undefined—設為 `true` 時禁止編輯文字,但仍允許 focus 與 selection
maxlengthnumber | undefined—限制最大字元數(並由 `admin-input-word-limit` 顯示計數)
classClassValue—根元素之自訂 class
typeInputTypeHTMLAttribute | undefined"text"HTML input type(如 `text`、`password`、`number`)
isErrorboolean | undefined—設為 `true` 時套用錯誤狀態樣式與 `aria-invalid`
idstring | undefined—透傳至內層 `input` 之 `id`;純透傳,未提供時不自動生成
namestring | undefined—透傳至內層 `input` 之 `name`,供原生表單提交使用

Events

名稱Payload說明
blurFocusEvent內層 `input` 失焦時轉發之原生事件
changeEvent內層 `input` 觸發原生 `change`(值變更並 commit)時轉發之原生事件
inputEvent內層 `input` 觸發原生 `input`(每次輸入)時轉發之原生事件
update:modelValuestring | numbermodelValue 更新時觸發

Slots

名稱Bindings說明
defaultany預設 slot
prefixany輸入框前綴 slot,常用於放置 icon
suffixany輸入框後綴 slot,常用於放置 icon、清除按鈕、字數計數

Expose

名稱簽名說明
inputHTMLInputElement | null內部原生 input 元素之 template ref,可用於程式化 focus / blur / select 等操作

admin-input-clear

Props

名稱型別預設值說明
classunknown——

Events

名稱Payload說明
clear—點擊清除按鈕、值已清空後觸發

Slots

名稱Bindings說明
default{}—

admin-input-password-toggle

Props

名稱型別預設值說明
classunknown——

admin-input-word-limit

Props

名稱型別預設值說明
classunknown——

更新紀錄

  • fix: 補上 Vue 核心 API 的顯式 import3c2c030
  • fix: 修正 admin-editor-link-bubble 的 input ref 綁定方式35c6a31
  • fix: 修正空值判斷與清除後密碼遮蔽還原2721ce4
  • feat: 表單元件補原生 id/name 屬性與 input/blur/change 事件2003547
  • fix: 將多個元件的按鈕類型設為 type="button",避免在表單中觸發提交事件f4f1bdd
  • chore: 啟用 vue/no-useless-v-bind 與 vue/prefer-separate-static-class16c34a8