vue 实现input封装
封装 Input 组件的基本实现
在 Vue 中封装 Input 组件可以通过创建一个可复用的自定义组件来实现,以下是一个基础示例:
创建 Input 组件文件 (BaseInput.vue)
<template>
<div class="base-input">
<label v-if="label">{{ label }}</label>
<input
:type="type"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
:placeholder="placeholder"
:disabled="disabled"
/>
</div>
</template>
<script>
export default {
name: 'BaseInput',
props: {
modelValue: {
type: [String, Number],
default: ''
},
type: {
type: String,
default: 'text'
},
label: {
type: String,
default: ''
},
placeholder: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
}
}
}
</script>
<style scoped>
.base-input {
margin-bottom: 15px;
}
.base-input label {
display: block;
margin-bottom: 5px;
}
.base-input input {
width: 100%;
padding: 8px 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
</style>
使用 v-model 支持
Vue 3 使用 modelValue 作为默认 prop 和 update:modelValue 作为默认事件来实现 v-model:
父组件中使用
<template>
<div>
<BaseInput v-model="username" label="用户名" placeholder="请输入用户名" />
<BaseInput v-model="password" type="password" label="密码" />
</div>
</template>
<script>
import BaseInput from './BaseInput.vue'
export default {
components: { BaseInput },
data() {
return {
username: '',
password: ''
}
}
}
</script>
添加验证功能
可以扩展组件以支持验证功能:
带验证的 Input 组件
<template>
<div class="base-input">
<label v-if="label">{{ label }}</label>
<input
:type="type"
:value="modelValue"
@input="handleInput"
@blur="validate"
:placeholder="placeholder"
:disabled="disabled"
:class="{ 'error': error }"
/>
<span v-if="error" class="error-message">{{ error }}</span>
</div>
</template>
<script>
export default {
props: {
// ...原有props
rules: {
type: Array,
default: () => []
}
},
data() {
return {
error: ''
}
},
methods: {
handleInput(e) {
this.$emit('update:modelValue', e.target.value)
this.error = ''
},
validate() {
if (this.rules.length) {
const failedRule = this.rules.find(rule => !rule.validator(this.modelValue))
this.error = failedRule ? failedRule.message : ''
}
}
}
}
</script>
<style scoped>
.error {
border-color: red;
}
.error-message {
color: red;
font-size: 12px;
display: block;
margin-top: 5px;
}
</style>
使用验证规则
<BaseInput
v-model="email"
label="邮箱"
:rules="[
{ validator: val => !!val, message: '邮箱不能为空' },
{ validator: val => /.+@.+\..+/.test(val), message: '请输入有效的邮箱' }
]"
/>
支持插槽增强灵活性
可以通过插槽让组件更灵活:
带插槽的 Input 组件
<template>
<div class="base-input">
<slot name="label">
<label v-if="label">{{ label }}</label>
</slot>
<div class="input-wrapper">
<slot name="prefix"></slot>
<input
:type="type"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
:placeholder="placeholder"
:disabled="disabled"
/>
<slot name="suffix"></slot>
</div>
<slot name="message">
<span v-if="error" class="error-message">{{ error }}</span>
</slot>
</div>
</template>
<style scoped>
.input-wrapper {
display: flex;
align-items: center;
}
</style>
使用插槽示例
<BaseInput v-model="searchText" placeholder="搜索...">
<template #prefix>
<SearchIcon />
</template>
<template #suffix>
<button @click="clearSearch">清除</button>
</template>
</BaseInput>
响应式设计考虑
可以添加响应式属性来控制不同屏幕尺寸下的样式:
响应式样式
<style scoped>
.base-input {
margin-bottom: 15px;
}
@media (max-width: 768px) {
.base-input {
margin-bottom: 10px;
}
.base-input input {
padding: 6px 8px;
}
}
</style>






