feat: 完成基础组件、布局组件和业务组件开发

This commit is contained in:
UGREEN USER
2026-01-28 14:41:09 +08:00
parent 1c831dbe69
commit b657c3d8aa
15 changed files with 994 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
<template>
<div class="g-input-wrapper">
<input
v-model="inputValue"
:type="type"
:placeholder="placeholder"
:disabled="disabled"
:class="inputClass"
@focus="handleFocus"
@blur="handleBlur"
/>
<button v-if="clearable && inputValue" @click="handleClear" class="clear-btn">×</button>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
interface Props {
modelValue: string | number
type?: 'text' | 'password' | 'email' | 'tel'
placeholder?: string
disabled?: boolean
clearable?: boolean
}
const props = withDefaults(defineProps<Props>(), {
type: 'text',
clearable: false
})
const emit = defineEmits<{
'update:modelValue': [value: string]
focus: [event: FocusEvent]
blur: [event: FocusEvent]
}>()
const inputValue = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val)
})
const focused = ref(false)
const inputClass = computed(() => [
'g-input',
{
'is-focused': focused.value,
'is-disabled': props.disabled
}
])
const handleFocus = (e: FocusEvent) => {
focused.value = true
emit('focus', e)
}
const handleBlur = (e: FocusEvent) => {
focused.value = false
emit('blur', e)
}
const handleClear = () => {
inputValue.value = ''
}
</script>
<style scoped lang="scss">
.g-input-wrapper {
@apply relative;
}
.g-input {
@apply w-full px-4 py-2.5 rounded-lg border-2 border-gray-200 transition-all duration-200;
&:focus {
@apply border-primary-500 outline-none shadow-md;
}
&.is-disabled {
@apply bg-gray-100 cursor-not-allowed;
}
}
.clear-btn {
@apply absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 text-xl;
}
</style>