vue 实现input封装
封装基础Input组件
创建一个基础的Input.vue文件,包含props接收父组件传递的参数:
<template>
<input
:type="type"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
:placeholder="placeholder"
:disabled="disabled"
class="base-input"
/>
</template>
<script>
export default {
name: 'BaseInput',
props: {
type: {
type: String,
default: 'text'
},
modelValue: {
type: [String, Number],
default: ''
},
placeholder: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
}
}
}
</script>
<style scoped>
.base-input {
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
}
</style>
实现v-model支持
使用Vue3的v-model语法糖或Vue2的.sync修饰符:
<!-- Vue3写法 -->
<BaseInput v-model="username" />
<!-- Vue2写法 -->
<BaseInput :value.sync="username" />
添加表单验证功能
扩展组件支持验证状态显示:
<template>
<div class="input-wrapper">
<input
<!-- 原有属性 -->
:class="{'error': error}"
/>
<span v-if="error" class="error-message">{{ errorMessage }}</span>
</div>
</template>
<script>
export default {
props: {
error: Boolean,
errorMessage: String
}
}
</script>
<style>
.error {
border-color: red;
}
.error-message {
color: red;
font-size: 12px;
}
</style>
添加插槽增强灵活性
支持前缀/后缀插槽:
<template>
<div class="input-container">
<span v-if="$slots.prefix" class="prefix">
<slot name="prefix"></slot>
</span>
<input <!-- 原有input --> />
<span v-if="$slots.suffix" class="suffix">
<slot name="suffix"></slot>
</span>
</div>
</template>
支持清除功能
添加清除按钮:
<template>
<div class="input-with-clear">
<input <!-- 原有属性 --> />
<button
v-if="showClear && modelValue"
@click="$emit('update:modelValue', '')"
class="clear-btn"
>×</button>
</div>
</template>
<script>
export default {
props: {
showClear: {
type: Boolean,
default: false
}
}
}
</script>
完整示例组件
综合所有功能的完整组件:
<template>
<div class="custom-input" :class="{'disabled': disabled}">
<label v-if="label" class="input-label">{{ label }}</label>
<div class="input-group">
<slot name="prefix"></slot>
<input
:type="type"
:value="modelValue"
@input="handleInput"
@blur="$emit('blur')"
@focus="$emit('focus')"
:placeholder="placeholder"
:disabled="disabled"
:class="{'error': error}"
/>
<button
v-if="clearable && modelValue"
@click="handleClear"
class="clear-btn"
>×</button>
<slot name="suffix"></slot>
</div>
<span v-if="error && errorMessage" class="error-message">
{{ errorMessage }}
</span>
</div>
</template>
<script>
export default {
name: 'CustomInput',
props: {
type: { /* 同上 */ },
modelValue: { /* 同上 */ },
label: String,
clearable: Boolean,
// 其他props...
},
methods: {
handleInput(e) {
this.$emit('update:modelValue', e.target.value)
},
handleClear() {
this.$emit('update:modelValue', '')
this.$emit('clear')
}
}
}
</script>
<style scoped>
/* 完整样式 */
.custom-input {
margin-bottom: 16px;
}
.input-group {
position: relative;
display: flex;
align-items: center;
}
.clear-btn {
position: absolute;
right: 8px;
background: transparent;
border: none;
cursor: pointer;
}
/* 其他样式... */
</style>
全局注册组件
在main.js中全局注册:
import CustomInput from '@/components/CustomInput.vue'
// Vue3
app.component('CustomInput', CustomInput)
// Vue2
Vue.component('CustomInput', CustomInput)






