Skip to content

BaInput 组件使用文档

组件概述

BaInput 是一个基于 Element Plus Input 封装的增强型输入组件,专为表单场景设计。它自动集成了表单验证、占位符智能生成、清空功能等特性,简化了表单输入组件的使用。

核心特性

  • 🎯 智能占位符:自动根据标签生成占位符文本
  • 表单集成:无缝集成 Element Plus 表单验证系统
  • 🧹 清空功能:内置清空按钮,提升用户体验
  • 📊 字数统计:支持显示输入字数限制
  • 🔧 灵活扩展:支持所有 Element Plus Input 的插槽和属性

基础使用

1. 简单输入框

vue
<template>
  <div>
    <!-- 基础用法 -->
    <BaInput v-model="username" label="用户名" prop="username" />
    
    <!-- 带自定义占位符 -->
    <BaInput 
      v-model="email" 
      label="邮箱" 
      prop="email" 
      placeholder="请输入您的邮箱地址"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const username = ref('')
const email = ref('')
</script>

2. 表单中使用

vue
<template>
  <el-form :model="form" :rules="rules" ref="formRef">
    <BaInput 
      v-model="form.username" 
      label="用户名" 
      prop="username"
      :rules="[{ required: true, message: '请输入用户名', trigger: 'blur' }]"
    />
    
    <BaInput 
      v-model="form.email" 
      label="邮箱" 
      prop="email"
      :rules="[
        { required: true, message: '请输入邮箱', trigger: 'blur' },
        { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
      ]"
    />
    
    <BaInput 
      v-model="form.phone" 
      label="手机号" 
      prop="phone"
      :rules="[
        { required: true, message: '请输入手机号', trigger: 'blur' },
        { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
      ]"
    />
    
    <el-button type="primary" @click="submitForm">提交</el-button>
  </el-form>
</template>

<script setup>
import { ref, reactive } from 'vue'

const formRef = ref()
const form = reactive({
  username: '',
  email: '',
  phone: ''
})

const rules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' }
  ],
  email: [
    { required: true, message: '请输入邮箱', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
  ],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
  ]
}

const submitForm = async () => {
  try {
    await formRef.value.validate()
    console.log('表单数据:', form)
    // 提交逻辑...
  } catch (error) {
    console.log('表单验证失败:', error)
  }
}
</script>

API 参考

Props 属性

属性名类型默认值说明
placeholderString-自定义占位符文本
v-modelString/Number-输入框绑定值
labelString-表单项标签(通过 $attrs 传递)
propString-表单验证字段名(通过 $attrs 传递)
rulesObject/Array-表单验证规则(通过 $attrs 传递)

Attributes 属性(继承 Element Plus Input)

BaInput 继承了 Element Plus Input 的所有属性,常用的包括:

属性名类型默认值说明
typeString'text'输入框类型
maxlengthNumber-最大输入长度
minlengthNumber-最小输入长度
show-word-limitBooleantrue是否显示输入字数统计
clearableBooleantrue是否可清空
disabledBooleanfalse是否禁用
readonlyBooleanfalse是否只读
autofocusBooleanfalse是否自动聚焦

Slots 插槽

插槽名说明
prefix输入框头部内容
suffix输入框尾部内容
prepend输入框前置内容
append输入框后置内容
default默认插槽(输入框后的内容)

Events 事件(继承 Element Plus Input)

事件名说明回调参数
blur在 Input 失去焦点时触发(event: Event)
focus在 Input 获得焦点时触发(event: Event)
change仅在输入框失去焦点或用户按下回车时触发(value: string | number)
input在 Input 值改变时触发(value: string | number)
clear在点击由 clearable 属性生成的清空按钮时触发

完整业务示例

用户信息编辑表单

vue
<template>
  <div class="user-form">
    <el-card shadow="never">
      <template #header>
        <div class="card-header">
          <span>用户信息编辑</span>
        </div>
      </template>
      
      <el-form 
        :model="userInfo" 
        :rules="formRules" 
        ref="userFormRef" 
        label-width="100px"
      >
        <el-row :gutter="20">
          <el-col :span="12">
            <BaInput 
              v-model="userInfo.username" 
              label="用户名" 
              prop="username"
              maxlength="20"
            />
          </el-col>
          <el-col :span="12">
            <BaInput 
              v-model="userInfo.realName" 
              label="真实姓名" 
              prop="realName"
              maxlength="10"
            />
          </el-col>
        </el-row>
        
        <el-row :gutter="20">
          <el-col :span="12">
            <BaInput 
              v-model="userInfo.email" 
              label="邮箱" 
              prop="email"
              type="email"
            />
          </el-col>
          <el-col :span="12">
            <BaInput 
              v-model="userInfo.phone" 
              label="手机号" 
              prop="phone"
            />
          </el-col>
        </el-row>
        
        <BaInput 
          v-model="userInfo.address" 
          label="地址" 
          prop="address"
          type="textarea"
          :rows="3"
          maxlength="200"
        />
        
        <BaInput 
          v-model="userInfo.website" 
          label="个人网站" 
          prop="website"
          placeholder="https://example.com"
        >
          <template #prepend>https://</template>
        </BaInput>
        
        <BaInput 
          v-model="userInfo.searchKeyword" 
          label="搜索关键词" 
          prop="searchKeyword"
        >
          <template #append>
            <el-button icon="Search" @click="handleSearch" />
          </template>
        </BaInput>
        
        <div class="form-footer">
          <el-button @click="resetForm">重置</el-button>
          <el-button type="primary" @click="submitForm">保存</el-button>
        </div>
      </el-form>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { userService } from '@/api/user'

const userFormRef = ref()
const userInfo = reactive({
  username: '',
  realName: '',
  email: '',
  phone: '',
  address: '',
  website: '',
  searchKeyword: ''
})

const formRules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 20, message: '用户名长度3-20位', trigger: 'blur' }
  ],
  realName: [
    { required: true, message: '请输入真实姓名', trigger: 'blur' }
  ],
  email: [
    { required: true, message: '请输入邮箱', trigger: 'blur' },
    { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
  ],
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
  ]
}

const submitForm = async () => {
  try {
    await userFormRef.value.validate()
    await userService.update(userInfo)
    $sdk.msgSuccess('保存成功')
  } catch (error) {
    console.error('保存失败:', error)
  }
}

const resetForm = () => {
  userFormRef.value.resetFields()
}

const handleSearch = () => {
  if (userInfo.searchKeyword) {
    // 执行搜索逻辑
    console.log('搜索关键词:', userInfo.searchKeyword)
  }
}
</script>

<style scoped>
.user-form {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.card-header {
  font-size: 18px;
  font-weight: bold;
}

.form-footer {
  text-align: center;
  margin-top: 30px;
}

.form-footer .el-button {
  margin: 0 10px;
}
</style>

高级用法

1. 带图标和按钮的输入框

vue
<template>
  <!-- 前置图标 -->
  <BaInput 
    v-model="searchText" 
    label="搜索" 
    prop="search"
  >
    <template #prefix>
      <el-icon><Search /></el-icon>
    </template>
  </BaInput>
  
  <!-- 后置按钮 -->
  <BaInput 
    v-model="domain" 
    label="域名" 
    prop="domain"
  >
    <template #prepend>https://</template>
    <template #append>.com</template>
  </BaInput>
  
  <!-- 复合型输入框 -->
  <BaInput 
    v-model="price" 
    label="价格" 
    prop="price"
  >
    <template #prepend>¥</template>
    <template #append>
      <el-select v-model="currency" style="width: 80px">
        <el-option label="CNY" value="CNY" />
        <el-option label="USD" value="USD" />
      </el-select>
    </template>
  </BaInput>
</template>

<script setup>
import { ref } from 'vue'
import { Search } from '@element-plus/icons-vue'

const searchText = ref('')
const domain = ref('')
const price = ref('')
const currency = ref('CNY')
</script>

2. 文本域输入

vue
<template>
  <BaInput 
    v-model="description" 
    label="描述" 
    prop="description"
    type="textarea"
    :rows="4"
    maxlength="500"
    show-word-limit
    placeholder="请输入详细描述..."
  />
</template>

<script setup>
import { ref } from 'vue'

const description = ref('')
</script>

3. 密码输入框

vue
<template>
  <BaInput 
    v-model="password" 
    label="密码" 
    prop="password"
    type="password"
    show-password
    maxlength="20"
  />
</template>

<script setup>
import { ref } from 'vue'

const password = ref('')
</script>

最佳实践

1. 表单验证策略

javascript
// 基础验证规则
const basicRules = {
  required: { required: true, message: '请输入内容', trigger: 'blur' },
  email: { type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' },
  phone: { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' },
  url: { type: 'url', message: '请输入正确的网址', trigger: 'blur' }
}

// 使用示例
const formRules = {
  username: [basicRules.required],
  email: [basicRules.required, basicRules.email],
  phone: [basicRules.required, basicRules.phone]
}

2. 数据绑定优化

vue
<template>
  <!-- 推荐:使用 reactive 管理表单数据 -->
  <el-form :model="formData">
    <BaInput v-model="formData.username" label="用户名" prop="username" />
    <BaInput v-model="formData.email" label="邮箱" prop="email" />
  </el-form>
</template>

<script setup>
import { reactive } from 'vue'

const formData = reactive({
  username: '',
  email: ''
})
</script>

3. 错误处理

javascript
const submitForm = async () => {
  try {
    await formRef.value.validate()
    // 提交逻辑
    await submitApi(formData.value)
    $sdk.msgSuccess('提交成功')
  } catch (error) {
    if (error instanceof Error) {
      // 表单验证错误
      console.log('表单验证失败:', error)
    } else {
      // 提交错误
      $sdk.msgError(error.message || '提交失败')
    }
  }
}

注意事项

  1. 占位符生成:当未设置 placeholder 时,组件会自动根据 label 生成"请输入[标签]"的占位符
  2. 表单集成:使用 label 和 prop 属性时,组件会自动包装为表单项
  3. 清空功能:默认启用 clearable 属性,用户可点击清空按钮
  4. 字数限制:设置 maxlength 时会自动显示字数统计
  5. 属性透传:支持所有 Element Plus Input 的属性和事件

常见问题

Q: 如何自定义占位符文本?

A: 直接使用 placeholder 属性:

vue
<BaInput v-model="value" label="姓名" placeholder="请输入您的姓名" />

Q: 如何在输入框前后添加内容?

A: 使用 prepend 和 append 插槽:

vue
<BaInput v-model="url" label="网址">
  <template #prepend>https://</template>
  <template #append>.com</template>
</BaInput>

Q: 如何实现输入验证?

A: 结合 Element Plus Form 使用:

vue
<el-form :model="form" :rules="rules" ref="formRef">
  <BaInput v-model="form.email" label="邮箱" prop="email" />
</el-form>

Q: 如何处理特殊输入类型?

A: 通过 type 属性设置:

vue
<!-- 密码输入 -->
<BaInput v-model="pwd" type="password" show-password />

<!-- 数字输入 -->
<BaInput v-model="num" type="number" />

<!-- 文本域 -->
<BaInput v-model="content" type="textarea" :rows="4" />

Q: 如何监听输入事件?

A: 监听原生事件:

vue
<BaInput 
  v-model="value" 
  @input="handleInput"
  @change="handleChange"
  @focus="handleFocus"
  @blur="handleBlur"
/>