You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
2.6 KiB
Vue

<template>
<div>
<div :class="inputClass">
<slot name="addonBefore" />
<input
class="input"
:type="type"
:value="inputValue"
@input="handleInput"
:focus="inputFocus"
@focus="handleFocus"
@blur="handleBlur"
:placeholder="placeholder"
:maxlength="maxlength"
/>
<icon
v-show="modelValue && allowClear"
type="clear"
size="16"
@tap="clearInput()"
/>
<slot name="addonAfter" />
</div>
<div v-if="inputError && rule" class="error-tips">{{ rule.message }}</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from '../utils/transformVue'
const $emit = defineEmits(['update:modelValue', 'input', 'focus', 'blur'])
const props = defineProps({
className: {
type: String,
default: '',
},
type: {
type: String,
default: 'text',
},
modelValue: {
type: String,
default: '',
},
placeholder: {
type: String,
default: '',
},
allowClear: {
type: Boolean,
default: false,
},
rule: {
type: Object,
default: null,
},
maxlength: {
type: Number,
default: 140,
},
})
const inputFocus = ref(false)
const inputError = ref(false)
// const inputKey = ref(0);
const inputClass = computed(() => {
return [
// @ts-ignore
props.class,
'form-input-item',
{ focus: inputFocus.value, error: inputError.value },
]
})
const inputValue = computed(() => {
return props.modelValue || ''
})
const handleBlur = (event: any) => {
inputFocus.value = false
if (props.rule && props.rule.trigger === 'blur') {
inputError.value = !props.rule.reg.test(props.modelValue || '')
}
$emit('blur', event)
}
const handleFocus = (event: any) => {
inputFocus.value = true
$emit('blur', event)
}
const handleInput = (event: any) => {
if (!(props.maxlength && event.detail.value.length > props.maxlength)) {
$emit('update:modelValue', event.detail.value)
$emit('input', event.detail.value)
}
// 强制刷新input
// inputKey.value++;
}
const clearInput = () => {
$emit('update:modelValue', null)
$emit('input', null)
inputFocus.value = true
}
</script>
<style lang="scss" scoped>
$primary-color: #337eff;
$error-color: #f56c6c;
.form-input-item {
border-bottom: 1px solid #dcdfe5;
padding: 10px 10px 5px 0px;
display: flex;
height: 44px;
align-items: center;
&.focus {
border-color: $primary-color;
}
&.error {
border-color: $error-color;
}
}
.input {
flex: 1;
border: none;
outline: none;
}
.error-tips {
color: $error-color;
font-size: 12px;
margin-top: 5px;
}
</style>