94 lines
2.2 KiB
Vue
94 lines
2.2 KiB
Vue
<template>
|
|
<div class="form-control">
|
|
<label class="label" v-if="label || icon">
|
|
<component :is="icon" class="w-4 h-4" v-if="icon" />
|
|
<span class="label-text" v-if="label">{{ label }}</span>
|
|
</label>
|
|
|
|
<div class="input-group">
|
|
<input
|
|
:type="type"
|
|
:placeholder="placeholder"
|
|
:class="inputClasses"
|
|
:value="modelValue"
|
|
@input="handleInput"
|
|
@blur="handleBlur"
|
|
v-bind="$attrs"
|
|
/>
|
|
<slot name="suffix"></slot>
|
|
</div>
|
|
|
|
<label class="label" v-if="error">
|
|
<span class="label-text-alt text-error">{{ error }}</span>
|
|
</label>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
|
|
interface Props {
|
|
modelValue?: string | number
|
|
label?: string
|
|
placeholder?: string
|
|
error?: string
|
|
type?: 'text' | 'number' | 'email' | 'password'
|
|
size?: 'xs' | 'sm' | 'md' | 'lg'
|
|
variant?: 'default' | 'bordered' | 'ghost'
|
|
icon?: any
|
|
disabled?: boolean
|
|
readonly?: boolean
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
type: 'text',
|
|
size: 'md',
|
|
variant: 'bordered'
|
|
})
|
|
|
|
const emit = defineEmits<{
|
|
'update:modelValue': [value: string | number]
|
|
'blur': [event: FocusEvent]
|
|
}>()
|
|
|
|
defineOptions({
|
|
inheritAttrs: false
|
|
})
|
|
|
|
const inputClasses = computed(() => {
|
|
const baseClasses = ['input', 'flex-1']
|
|
|
|
// 添加变体样式
|
|
if (props.variant === 'bordered') baseClasses.push('input-bordered')
|
|
else if (props.variant === 'ghost') baseClasses.push('input-ghost')
|
|
|
|
// 添加尺寸样式
|
|
if (props.size === 'xs') baseClasses.push('input-xs')
|
|
else if (props.size === 'sm') baseClasses.push('input-sm')
|
|
else if (props.size === 'lg') baseClasses.push('input-lg')
|
|
|
|
// 添加错误样式
|
|
if (props.error) baseClasses.push('input-error')
|
|
|
|
// 添加状态样式
|
|
if (props.disabled) baseClasses.push('input-disabled')
|
|
|
|
return baseClasses
|
|
})
|
|
|
|
const handleInput = (event: Event) => {
|
|
const target = event.target as HTMLInputElement
|
|
let value: string | number = target.value
|
|
|
|
// 如果是数字类型,转换为数字
|
|
if (props.type === 'number' && value !== '') {
|
|
value = Number(value)
|
|
}
|
|
|
|
emit('update:modelValue', value)
|
|
}
|
|
|
|
const handleBlur = (event: FocusEvent) => {
|
|
emit('blur', event)
|
|
}
|
|
</script> |