目录
- 目的
- 源码
- 关键文档,大部分复制el-form
- Attributes
- Methods
- Events
- Slot
- Scoped Slot
- Form-Item Attributes
- Row Attributes
- Col Attributes
- 基本用法
- 使用场景
目的
- el-form 表单配置化,后期可以利用后端进行配置表单
- 支持栅格布局
- el-form 属性大部分都支持
- 公共配置可以统一处理,如trim、input宽度等
- 最基本的组件,利用这组件后期可以优化简单的新增编辑弹窗写法
源码
<script>
export default {
props: {
model: {
type: Object,
default: () => {},
},
rowItems: {
type: Array,
default: () => [],
},
formItems: {
type: Array,
default: () => [],
},
},
data() {
return {
_model: {},
};
},
mounted() {
// 用于重置,时间范围选择组件时重置不了endTime
this._model = { ...this.model };
// 默认选中光标,设置ref=focus
this.focus();
},
methods: {
// 处理v-modelv value 值
hanlderValue(prop) {
// 时间范围选择组件处理
if (Array.isArray(prop) && prop.length > 0) {
const [first] = prop;
if (this.model[first]) {
const data = prop.map((key) => this.model[key]);
return data;
}
return [];
}
return this.model[prop];
},
// 处理FormItem绑定值
hanlderFormItemProp(prop) {
// 时间范围选择组件处理
if (Array.isArray(prop) && prop.length > 0) {
// 处理时间范围选择的
const [first] = prop;
return first;
}
return prop;
},
// 处理改变值
hanlderModel(prop, value) {
// 时间范围选择组件处理
if (prop && Array.isArray(prop)) {
if (Array.isArray(value)) {
// 数组对应值
prop.forEach((key, index) => {
this.model[key] = value && value.length > 0 ? value[index] : '';
});
} else if ([null, '', undefined].includes(value)) {
// 数组有清除按钮时,数组一起清理
prop.forEach((key) => {
this.model[key] = value;
});
}
} else {
this.model[prop] = value;
}
},
focus() {
this.$nextTick(() => {
if (this.$refs.focus) {
setTimeout(() => {
this.$refs.focus.focus();
}, 100);
}
});
},
validate(...props) {
return this.$refs.form.validate(...props);
},
// 对部分字段进行校验
validateField(...props) {
return this.$refs.form.validateField(...props);
},
// 对整个表单进行重置
resetFields() {
Object.assign(this.model, this._model);
this.$refs.form.resetFields();
},
// 移除表单项的校验结果
clearValidate(...props) {
this.$refs.form.clearValidate(...props);
},
},
render(createElement) {
// 父级slots
// form-item label slot
const slotLabel = (slotName) => createElement(
'template',
{
slot: 'label',
},
this.$slots[slotName],
);
// formItem 组件
const formItem = (item) => createElement(
'el-form-item',
{
props: {
...item,
prop: this.hanlderFormItemProp(item.prop),
},
scopedSlots: {
error: (prop) => this.$scopedSlots[item.slotErrorName] && this.$scopedSlots[item.slotErrorName](prop),
},
},
[
// 加入label插槽
item.slotLabelName ? slotLabel(item.slotLabelName) : '',
// 有插槽优先
item.slotName ? this.$slots[item.slotName] : createElement(item.type || 'el-input', {
//
ref: item.ref,
attrs: {
...item.props,
},
props: {
clearable: true,
...item.props,
value: this.hanlderValue(item.prop),
},
// 加样式
style: {
width: '240px',
...(item.props && item.props.style),
},
on: {
...item.on,
change: (value) => {
// 重写change方法
if (item.on && item.on.change) {
item.on.change(value);
}
this.hanlderModel(item.prop, value);
},
// el-input 场景
input: (value) => {
this.hanlderModel(item.prop, value);
},
},
}),
],
);
// col 组件
const col = (item) => createElement('el-col', {
props: {
...item,
},
}, item.formItem ? [formItem(item.formItem)] : '');
// row组件
const row = (item) => createElement('el-row', {
props: {
...item,
},
}, item.cols.map((list) => col(list)));
return createElement(
'el-form',
{
ref: 'form',
props: {
...this.$attrs,
model: this.model,
},
on: {
...this.$listeners,
},
},
// rowItems 优先
this.rowItems.length ? this.rowItems.map((item) => row(item)) : this.formItems.map((item) => formItem(item)),
);
},
};
</script>
<style lang="scss" module="s"></style>
关键文档,大部分复制el-form
Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
model | 表单数据对象 | object | — | — |
rules | 表单验证规则 | object | — | — |
inline | 行内表单模式 | boolean | — | false |
label-position | 表单域标签的位置,如果值为 left 或者 right 时,则需要设置 label-width | string | right/left/top | right |
label-width | 表单域标签的宽度,例如 '50px'。作为 Form 直接子元素的 form-item 会继承该值。支持 auto 。 | string | — | — |
label-suffix | 表单域标签的后缀 | string | — | — |
hide-required-asterisk | 是否隐藏必填字段的标签旁边的红色星号 | boolean | — | false |
show-message | 是否显示校验错误信息 | boolean | — | true |
inline-message | 是否以行内形式展示校验信息 | boolean | — | false |
status-icon | 是否在输入框中显示校验结果反馈图标 | boolean | — | false |
validate-on-rule-change | 是否在 rules 属性改变后立即触发一次验证 | boolean | — | true |
size | 用于控制该表单内组件的尺寸 | string | medium / small / mini | — |
disabled | 是否禁用该表单内的所有组件。若设置为 true,则表单内组件上的 disabled 属性不再生效 | boolean | — | false |
-分割线- | --- | --- | --- | --- |
formItems | 表单内组件 | array | Form-Item | — |
rowItems | 表单内组件支持layout布局,优先等级高于formItems | array | Row Attributes | — |
Methods
方法名 | 说明 | 参数 |
---|
validate | 对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise | Function(callback: Function(boolean, object)) |
validateField | 对部分表单字段进行校验的方法 | Function(props: array | string, callback: Function(errorMessage: string)) |
resetFields | 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 | — |
clearValidate | 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 | Function(props: array | string) |
focus | 使 input 获取焦点 | - |
blur | 使 input 失去焦点,并隐藏下拉框 | - |
Events
事件名称 | 说明 | 回调参数 |
---|
validate | 任一表单项被校验后触发 | 被校验的表单项 prop 值,校验是否通过,错误消息(如果存在) |
Slot
Scoped Slot
name | 说明 |
---|
error | 自定义表单校验信息的显示方式,参数为 { error } |
Form-Item Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
prop | 表单域 model 字段,在使用 validate、resetFields 方法的情况下,该属性是必填的 | string | 传入 Form 组件的 model 中的字段 | — |
label | 标签文本 | string | — | — |
label-width | 表单域标签的的宽度,例如 '50px'。支持 auto 。 | string | — | — |
required | 是否必填,如不设置,则会根据校验规则自动生成 | boolean | — | false |
rules | 表单验证规则 | object | — | — |
error | 表单域验证错误信息, 设置该值会使表单验证状态变为error ,并显示该错误信息 | string | — | — |
show-message | 是否显示校验错误信息 | boolean | — | true |
inline-message | 以行内形式展示校验信息 | boolean | — | false |
size | 用于控制该表单域下组件的尺寸 | string | medium / small / mini | - |
Row Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
gutter | 栅格间隔 | number | — | 0 |
type | 布局模式,可选 flex,现代浏览器下有效 | string | — | — |
justify | flex 布局下的水平排列方式 | string | start/end/center/space-around/space-between | start |
align | flex 布局下的垂直排列方式 | string | top/middle/bottom | — |
tag | 自定义元素标签 | string | * | div |
Col Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
span | 栅格占据的列数 | number | — | 24 |
offset | 栅格左侧的间隔格数 | number | — | 0 |
push | 栅格向右移动格数 | number | — | 0 |
pull | 栅格向左移动格数 | number | — | 0 |
xs | <768px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
sm | ≥768px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
md | ≥992px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
lg | ≥1200px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
xl | ≥1920px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
tag | 自定义元素标签 | string | * | div |
基本用法
demo 直接使用formItems
属性来配置表单
<template>
<div>
<d-form-smart
ref="form"
:model="form"
label-width="150px"
label-position="left"
:form-items="formItems"
>
<template #slotErrorName>
<span>按钮</span>
</template>
<template #region-label>
<el-badge :value="12" class="item">
<span>自定义label</span>
</el-badge>
</template>
<template #btn>
<el-button type="primary" @click="submit">提交</el-button>
</template>
</d-form-smart>
</div>
</template>
<script>
export default {
data() {
return {
form: {
name: '',
region: '',
date: [],
delivery: false,
personnel: '',
radio: '',
checkbox: [],
cascader: [],
timeSelect: '',
datePicker: '',
startTime: '',
endTime: '',
rate: 0,
special: '',
desc: null,
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{
min: 3,
max: 5,
message: '长度在 3 到 5 个字符',
trigger: 'blur',
},
],
},
formItems: [
{
label: '名字',
prop: 'name',
type: 'el-input',
props: {
placeholder: '请输入内容',
},
},
{
label: '开关',
prop: 'delivery',
type: 'el-switch',
},
{
prop: 'region',
type: 'd-select-smart',
slotLabelName: 'region-label',
props: {
list: [],
},
},
{
label: '级联',
prop: 'cascader',
type: 'el-cascader',
props: {
options: [
{
value: 'zhinan',
label: '指南',
children: [
{
value: 'shejiyuanze',
label: '设计原则',
children: [
{
value: 'yizhi',
label: '一致',
},
{
value: 'fankui',
label: '反馈',
},
{
value: 'xiaolv',
label: '效率',
},
{
value: 'kekong',
label: '可控',
},
],
},
],
},
],
},
},
{
label: '时间选择',
prop: 'timeSelect',
type: 'el-time-select',
props: {
placeholder: '选择时间',
},
},
{
label: '日期选择',
prop: 'datePicker',
type: 'el-date-picker',
props: {
placeholder: '选择日期',
valueFormat: 'yyyy-MM-dd',
},
},
{
label: '日期范围选择',
prop: ['startTime', 'endTime'],
type: 'el-date-picker',
props: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
format: 'yyyy-MM-dd',
valueFormat: 'yyyy-MM-dd',
},
},
{
label: '评分',
prop: 'rate',
type: 'el-rate',
},
{
label: '备注',
prop: 'desc',
type: 'el-input',
props: {
placeholder: '请输入内容',
type: 'textarea',
style: {
width: '400px',
},
},
},
{
slotName: 'btn',
props: {},
},
],
};
},
methods: {
change(val) {
console.log('change', val);
},
submit(){
console.log(this.form);
}
},
};
</script>
使用场景
1. 通用列表搜索条件
queryItems: [
{
label: '属性编码',
prop: 'propertyValueCode',
props: {
placeholder: '属性编码',
},
},
{
label: '属性名称',
prop: 'name',
props: {
placeholder: '属性名称',
},
},
],
<d-form-smart
@submit.native.prevent
ref="query"
inline
:model="query"
label-width="80px"
label-position="right"
:form-items="queryItems"
>
</d-form-smart>
2.弹窗写法优化
- 简单的新增
- form v-model绑定的值
- rules 规则
- formItems 表单配置
async add() {
try {
// 重置表单
Object.assign(this.form, this.$options.data().form);
this.$msgbox({
customClass: ['custom-message-box'],
title: '新增属性',
message: this.$createElement('FormSmart', {
ref: 'form',
key: Math.random(), // 重新创建,不缓存
attrs: {
labelWidth: '100px',
labelPosition: 'right',
model: this.form,
rules: this.opRules,
formItems: opItems,
},
}),
closeOnClickModal: false,
showCancelButton: true,
confirmButtonText: '确定',
cancelButtonText: '取消',
beforeClose: async (action, instance, done) => {
if (action === 'confirm') {
await this.$refs.form.validate();
instance.confirmButtonLoading = true;
try {
// 请求接口编写的地方
instance.confirmButtonLoading = false;
done();
} catch (error) {
instance.confirmButtonLoading = false;
}
} else {
this.$refs.form.resetFields();
done();
}
},
});
} catch (error) {
console.error(error);
}
},
到此这篇关于element基于el-form智能的FormSmart表单组件的文章就介绍到这了,更多相关element FormSmart表单内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341