SpFormPlus 组件使用手册
概述
sp-form-plus 是一个基于 Element UI 的增强版表单组件,提供了更灵活的配置方式和更丰富的功能。支持多种表单类型(普通表单、搜索表单)和多种字段组件,支持自定义组件渲染,具有良好的扩展性。
基本用法
基础示例
ref=”formDataRef”
v-model=”formData”
:form-items=”formItems”
form-type=”normalForm”
label-width=”120px”
@submit=”onSearch”
/>
ref=”formDataRef”
v-model=”formData”
:form-items=”formItems”
form-type=”normalForm”
label-width=”120px”
@submit=”onSearch”
/>
API 文档
Props
Form Item 配置
每个表单项支持以下配置:
注意: field-change 事件在当前版本中已被注释,使用 v-model 或
componentProps.onChange 来处理字段变化。
SpFormPlus 支持以下字段类型:
{
fieldName: ‘username’,
label: ‘用户名’,
component: ‘input’,
value: ”,
componentProps: {
placeholder: ‘请输入用户名’,
maxlength: 50,
showWordLimit: true,
onChange: (value, formData) => {
console.log(‘输入值变化:’, value)
}
}
}
{
fieldName: ‘category’,
label: ‘分类’,
component: ‘select’,
value: ”,
componentProps: {
options: [
{ label: ‘选项1’, value: 1 },
{ label: ‘选项2’, value: 2, disabled:
true }
],
multiple: false,
clearable: true,
onChange: (value, formData) => {
console.log(‘选择变化:’, value)
}
}
}
{
fieldName: ‘gender’,
label: ‘性别’,
component: ‘radio’,
value: 1,
componentProps: {
options: [
{ label: ‘男’, value: 1 },
{ label: ‘女’, value: 2, disabled:
false }
]
}
}
{
fieldName: ‘hobbies’,
label: ‘爱好’,
component: ‘checkbox’,
value: [],
componentProps: {
options: [
{ label: ‘读书’, value: ‘reading’ },
{ label: ‘运动’, value: ‘sports’ },
{ label: ‘音乐’, value: ‘music’,
disabled: false }
]
}
}
{
fieldName: ‘enabled’,
label: ‘启用状态’,
component: ‘switch’,
value: false,
componentProps: {
activeColor: ‘#13ce66’,
inactiveColor: ‘#ff4949’,
activeText: ‘开’,
inactiveText: ‘关’,
disabled: (formData) => {
// 支持函数形式的动态禁用
return formData.readonly === true
}
}
}
{
fieldName: ‘date’,
label: ‘日期’,
component: ‘datepicker’,
value: ”,
componentProps: {
type: ‘date’,
placeholder: ‘请选择日期’,
format: ‘yyyy-MM-dd’,
valueFormat: ‘yyyy-MM-dd’
}
}
{
fieldName: ‘dateRange’,
label: ‘时间范围’,
component: ‘datetimepicker’,
value: [],
componentProps: {
type: ‘datetimerange’,
startPlaceholder: ‘开始日期’,
endPlaceholder: ‘结束日期’,
rangeSeparator: ‘至’,
defaultTime: [’00:00:00′, ’23:59:59′]
}
}
{
fieldName: ‘avatar’,
label: ‘头像’,
component: ‘imagepicker’,
value: ”,
componentProps: {
multiple: false,
limit: 1,
onChange: (value) => {
console.log(‘图片选择变化:’, value)
}
}
}
{
fieldName: ‘action’,
label: ‘操作’,
component: ‘button’,
componentProps: {
text: ‘点击操作’,
type: ‘primary’,
size: ‘medium’,
disabled: false,
loading: false,
class: ‘custom-button’,
onClick: (event) => {
console.log(‘按钮点击’, event)
}
}
}
{
fieldName: ‘group1’,
label: ‘基本信息’,
component: ‘group’
}
{
fieldName: ‘custom’,
label: ‘自定义字段’,
component: ({ value, props, onInput, h,
formData }) => {
return h(‘div’, { class:
‘custom-field’ }, [
h(‘span’, { style: ‘margin-right:
10px’ }, ‘当前值:’ + value),
h(‘el-button’, {
props: { size: ‘small’ },
on: {
click: () => onInput(‘新值_’ +
Date.now())
}
}, ‘更改值’)
])
}
}
v-model=”searchData”
form-type=”searchForm”
:form-items=”searchFormItems”
label-width=”80px”
@submit=”handleSearch”
@reset=”handleReset”
/>
ref=”formRef”
v-model=”formData”
form-type=”normalForm”
:form-items=”formItems”
label-width=”120px”
@submit=”handleSubmit”
/>
{
fieldName: ’email’,
label: ‘邮箱’,
component: ‘input’,
rules: [
{ required: true, message: ‘请输入邮箱’,
trigger: ‘blur’ },
{ type: ’email’, message: ‘请输入正确的邮箱格式’,
trigger: ‘blur’ }
]
}
{
fieldName: ‘phone’,
label: ‘手机号’,
component: ‘input’,
rules: [
{
validator: (rule, value, callback)
=> {
if (!value) {
callback(new Error(‘请输入手机号’))
} else if
(!/^1[3-9]\d{9}$/.test(value)) {
callback(new Error(‘请输入正确的手机号’))
} else {
callback()
}
},
trigger: ‘blur’
}
]
}
{
fieldName: ‘reason’,
label: ‘原因’,
component: ‘input’,
isShow: (value) => {
// 只有当状态为禁用时才显示
return this.formData.status === 0
}
}
内联表单使用 CSS Grid 布局,自动适应容器宽度:
v-model=”formData”
:form-items=”formItems”
inline
form-type=”searchForm”
label-width=”100px”
@submit=”handleSubmit”
/>
使用计算属性根据表单数据动态生成表单项:
computed: {
formItems() {
const items = [
{
fieldName: ‘type’,
label: ‘类型’,
component: ‘select’,
value: ”,
componentProps: {
options: [
{ label: ‘个人’, value:
‘personal’ },
{ label: ‘企业’, value:
‘company’ }
],
onChange: (value, formData)
=> {
// 清空关联字段
if (value !== ‘company’) {
this.$set(formData,
‘companyName’, ”)
}
}
}
}
]
// 根据类型动态添加字段
if (this.formData.type === ‘company’)
{
items.push({
fieldName: ‘companyName’,
label: ‘公司名称’,
component: ‘input’,
value: ”,
rules: [
{ required: true, message: ‘请输入公司名称’,
trigger: ‘blur’ }
]
})
}
return items
}
}
使用 componentProps.onChange 实现字段间的联动:
{
fieldName: ‘province’,
label: ‘省份’,
component: ‘select’,
value: ”,
componentProps: {
options: this.provinces,
onChange: (value, formData) => {
// 清空城市选择
this.$set(formData, ‘city’, ”)
this.$set(formData, ‘district’, ”)
// 加载对应城市数据
this.loadCities(value).then(cities
=> {
// 更新城市字段的选项
this.updateCityOptions(cities)
})
}
}
},
{
fieldName: ‘city’,
label: ‘城市’,
component: ‘select’,
value: ”,
componentProps: {
options: this.cities,
onChange: (value, formData) => {
// 清空区县选择
this.$set(formData, ‘district’, ”)
// 加载区县数据
this.loadDistricts(value)
}
}
}
通过 formItemClass 为特定字段添加自定义样式:
{
fieldName: ‘special’,
label: ‘特殊字段’,
component: ‘input’,
value: ”,
formItemClass: ‘custom-form-item
highlight-field’,
tip: ‘这是一个重要字段’
}
.custom-form-item
{
&.highlight-field {
.el-form-item__label {
color: #f56c6c;
font-weight: bold;
&::before {
content: ‘★ ‘;
color: #ff4949;
}
}
.el-input__inner {
border-color: #f56c6c;
}
}
}
// 搜索表单特殊样式
.sp-form-plus–search-form {
.custom-form-item {
background-color: rgba(245, 108, 108,
0.1);
padding: 8px;
border-radius: 4px;
}
}
// 分组标题样式
.form-field-group {
position: relative;
padding: 8px;
color: #333;
font-size: 15px;
border-bottom: 1px solid #f1f2f5;
margin-bottom: 18px;
&::before {
position: absolute;
top: 11px;
bottom: 11px;
left: 0;
width: 2px;
background-color: var(–primary);
content: ”;
}
}
// 内联表单网格布局
.sp-form-plus–inline {
.sp-form-plus__wapper {
display: grid;
grid-template-columns:
repeat(auto-fit, minmax(320px, 1fr));
gap: 8px;
}
}
除了直接使用 SpFormPlus 组件外,还提供了 useForm Composable API,用于更灵活的表单管理。
import {
useForm } from ‘@/composables/useForm’
export default {
setup() {
const { Form, FormApi } = useForm({
formProps: {
labelWidth: ‘120px’
},
formItems: [
{
prop: ‘name’,
label: ‘姓名’,
type: ‘input’,
placeholder: ‘请输入姓名’,
rules: [
{ required: true, message: ‘请输入姓名’,
trigger: ‘blur’ }
]
},
{
prop: ’email’,
label: ‘邮箱’,
type: ‘input’,
placeholder: ‘请输入邮箱’
}
],
rules: {
email: [
{ type: ’email’, message: ‘请输入正确的邮箱格式’,
trigger: ‘blur’ }
]
},
initialValues: {
name: ”,
email: ”
}
})
return {
Form,
FormApi
}
}
}
useForm 支持以下字段类型:
FormApi 提供以下方法:
- :用于数据筛选,带有查询/重置按钮,具有特殊的背景样式
- componentProps.onChange 处理字段变化
- ref 调用 validate() 方法进行手动验证
- componentProps.onChange 中执行重度计算
A: 有以下几种方式:
- @submit
事件:@submit=”handleSubmit”
- this.$refs.formRef.validate()
A:
- this.$refs.formRef.resetField() 方法
A: 将 component 属性设置为函数:
component: ({
value, props, onInput, h, formData }) => {
return h(‘div’, ‘自定义内容’)
}
A: 在 componentProps.onChange 中处理:
componentProps:
{
onChange: (value, formData) => {
// 修改其他字段的值
this.$set(formData, ‘otherField’, ”)
}
}
A: field-change 事件在当前版本中已被注释,请使用:
A: 在 rules 中使用自定义验证器:
rules: [{
validator: async (rule, value,
callback) => {
try {
await this.checkValueExists(value)
callback()
} catch (error) {
callback(new Error(‘验证失败’))
}
}
}]
A: 使用 isShow 函数:
{
fieldName: ‘conditionalField’,
isShow: (value) =>
this.formData.showCondition === true
}
A: 展开/收起按钮已实现 UI 但功能暂未完善,当前版本的
toggleExtend 方法为空实现。
A:
- 是 Composable API,提供更灵活的编程式表单管理
A: 设置字段类型为 custom 并提供 render 函数:
{
prop: ‘customField’,
label: ‘自定义字段’,
type: ‘custom’,
render: (h, formData) => {
return h(‘div’, ‘自定义内容’)
}
}
A:
- 可选择日期时间范围,支持 datetimerange 类型