引入
import { FormPage } from 'adminpage-vue3'
思路介绍
本组件是基于element-UI进行快速搭建表单页的依赖,为前端静态逻辑处理,方便基础表单的渲染,将栅格属性,基础校验交由组件内部进行实现
最简示例
<template>
<FormPage v-model="formData" :formConfig="config" />
</template>
<script setup>
import { FormPage } from 'page-vue3'
import { ref } from 'vue'
const formData = ref({})
const config= [
{
label: '选择',
key: 'select',
type: 'select',
childConfig: {
type: 'option',
keys: {
value: 'key',
label: 'label'
},
bind: {},
list: [
{
label: '选项1',
key: 'checkbox1',
},
{
label: '选项2',
key: 'checkbox2',
}
]
}
},
{
label: '输入',
key: 'input',
defaultValue: '1',
notNull: true
},
{
label: '整数',
key: 'isInt',
isInt: true
},
{
label: '数值',
key: 'isNumber',
isNumber: true
},
{
label: '小数部分长度5',
key: 'isNumber5',
isNumber: 5
},
{
label: '小数部分长度5可负数',
key: 'isMinusNumber',
isMinusNumber: 5
},
{
label: '数字输入',
key: 'inputNumber',
notNull: true,
type: 'inputNumber',
bind: {
step: 1,
min: 0
}
}
]
</script>
FormPage-vue3 API汇总
属性
属性名 | 说明 | 类型 | 默认值 | 开始版本 |
---|---|---|---|---|
v-model | 双向绑定,表单数据 | Object | {} | 1.0.0 |
formConfig | 表单项配置,详见formConfig-type | Array | [] | 1.0.0 |
span | 表单栅格占据的列数(24栅格布局) | [Number, String] | 24 | 1.0.0 |
validateHandle | 外部校验函数,返回String时,该String将作为异常抛出,返回Array<String>时,每个String都作为单独异常进行抛出 | Function | () => ‘’ | 1.0.0 |
showText | 非表单模式,仅显示内容,不渲染表单输入 | Boolean | - | 1.0.0 |
插槽
插槽名 | 说明 | 开始版本 |
---|---|---|
[你设定的slotName] | 本组件内部使用了大量的动态组件,方便配置,可阅读文档自行设置插槽名 | 1.0.0 |
Exposes
值名 | 说明 | 开始版本 |
---|---|---|
validate() | 执行表单校验 | 1.0.0 |
setInitParams() | 初始化表单绑定值 | 1.0.3 |
自定义对象
formConfig(array<object> 类型)
属性名 | 说明 | 类型 | 默认值 | 开始版本 |
---|---|---|---|---|
key | 字段key值,该值将作用于表单modelValue的key值,当type为times时详见当type=times时 | String | - | 1.0.0 |
type | 详见下文 formConfig-type | String/vue3Component | ‘input’ | 1.0.0 |
label | 表单标签文本 | String | - | 1.0.0 |
noLabel | 搜索表单无标签文本标识,为true时将不显示标签文本 | Boolean | false | 1.0.0 |
bind | 表单搜索项属性绑定,将直接作用于表单筛选框的绑定,当type为times时详见当type=times时 | Object | 默认值可详见当type不为时间类型时 bind默认值 与 当type为时间类型时 bind默认值 | 1.0.0 |
defaultValue | 默认参数,当type为times时详见当type=times时 | String | - | 1.0.0 |
slotName | 插槽名称 将整个搜索项暴露给父页面进行使用 | String | - | 1.0.0 |
childSlot | 子插槽名,当组件结构为<el-select><el-option><\el-option></el-select>时,可将type设置为 select,通过子插槽渲染option | String | - | 1.0.0 |
notNull | 必填项声明,填写时将对该项是否填写进行校验 | Boolean | - | 1.0.0 |
isInt | 整数填写声明,填写时将对该项是否为整数进行校验 | Boolean | - | 1.0.0 |
isNumber | 数值【仅正数】填写声明(小数),填写时将对该项是否为数值进行校验,当接受参数为数字时,该数字将被作为小数位数参与校验,当为true时,小数位数长度不限制 | [Boolean,Number] | - | 1.0.0 |
isMinusNumber | 数值【可负数】填写声明(小数),填写时将对该项是否为数值进行校验,当接受参数为数字时,该数字将被作为小数位数参与校验,当为true时,小数位数长度不限制 | [Boolean,Number] | - | 1.0.0 |
formConfig-type
值 / 值类型 | 值详情 | 说明 | 开始版本 |
---|---|---|---|
‘times’ | 固定文本times | 将渲染分开为两个的时间筛选器,key、bind、defaultValue详见当type=times时 | 1.0.0 |
‘slot’ | 固定文本slot | 该搜索项将索引页面插槽进行渲染(寻找slotName命名插槽) | 1.0.0 |
String | element相关组件标签文本(以<el-time-picker>为例:‘el-time-picker’|‘time-picker’|‘ElTimePicker’|‘TimePicker’均可) | 将捕获element-UI相关组件,并通过v-model将值与页面搜索项进行绑定 | 1.0.0 |
类型为 VueComponent | vue3组件对象 | 将该组件进行绑定并通过v-model绑定值,逻辑与主要处理的element-ui的相关标签保持一致 | 1.0.0 |
当type=times时
属性名 | 说明 | 类型 | 默认值 | 开始版本 |
---|---|---|---|---|
startDefaultValue | 开始时间默认参数 | String | - | 1.0.0 |
endDefaultValue | 结束时间默认参数 | String | - | 1.0.0 |
startBind | 开始时间属性绑定 | Object | 详见 当type为时间类型时 bind默认值 | 1.0.0 |
endBind | 结束时间属性绑定 | Object | 详见 当type为时间类型时 bind默认值 | 1.0.0 |
startKey | 开始时间绑定Key | Object | startTime | 1.0.0 |
endKey | 结束时间绑定Key | Object | endTime | 1.0.0 |
当type不为时间类型时的 bind默认值(Object类型)
属性名 | 默认值 | 开始版本 |
---|---|---|
placeholder | label的值 | 1.0.0 |
clearable | true | 1.0.0 |
style | width: 200px | 1.0.0 |
当type为时间类型时的 bind默认值(Object类型)
属性名 | 默认值 | 开始版本 |
---|---|---|
style | width: 190px | 1.0.0 |
type | datetime | 1.0.0 |
placeholder | 请选择时间 | 1.0.0 |
format | YYYY-MM-DD HH:mm:ss | 1.0.0 |
valueFormat | YYYY-MM-DD HH:mm:ss | 1.0.0 |
Exposes
validate
本方法为校验函数,返回当前表单校验结果
校验通过时返回true
校验失败返回false
返回结果为Promise 请注意处理
<template>
<div>
<div style="padding: 10px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
<el-button type="primary" @click="validateDate">校验</el-button>
</div>
</div>
</template>
<script setup>
import { FormPage } from 'page-vue3'
const formData = ref({})
const FormPageRef = ref(null)
async function validateDate() {
const isOk = await FormPageRef.value.validate()
console.log('isOk', isOk)
}
const config = [
{
label: '输入',
key: 'input',
isMinusNumber: 1,
},
]
</script>
<style lang="scss" scoped></style>
属性: formConfig(表单项设置)
搜索项设置接收数组类型,每项设置均为对象,结构为
{
key:String,
label:String,
type:String || VueComponent || 'times' || 'slot', // type:'input' || type:ElInput || type:'times' || type:'slot'
noLabel:Boolean,
defaultValue:Any,
bind:Object,
childSlot:String,
// type='times'
startDefaultValue:String,
endDefaultValue:String,
startBind:Object,
endBind:Object,
startKey:String,
endKey:String,
// type='slot'
slotName:String,
//校验配置项
notNull:Boolean,
isInt:Boolean,
isNumber:Boolean || Number,
isMinusNumber:Boolean || Number,
}
key
本字段将设置为搜索时的属性key
字段,当type=times 时,将设置为startKey
与endKey
(默认为startTime
与endTime
)
label
将作为表单label进行渲染
noLabel
声明本字段,将取消显示该项的label
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: '输入',
key: 'input',
},
{
label: '输入',
key: 'input',
noLabel: true,
},
]
</script>
defaultValue
声明本字段默认值,首次加载时,初始渲染时均将该项设为该值
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
{{ formData }}
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: '输入',
key: 'input',
defaultValue: 1,
},
{
label: '输入',
key: 'input2',
defaultValue: 2,
},
]
</script>
bind
本属性将直接作用于表单项渲染绑定,例如
{
label: '电话',
type:'input',
key: 'phone',
bind:{
type:'textarea',
placeholder:'占位文本',
style:'color:red',
class:'testClass'
}
}
将渲染为·<el-input v-model="phone" type="textarea" placeholder="占位文本" style="color:red" class="testClass" />
示例代码如下
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
{{ formData }}
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: '电话',
type: 'input',
key: 'phone',
bind: {
type: 'textarea',
placeholder: '占位文本',
style: 'color:red',
class: 'testClass',
},
},
]
</script>
非时间类型的bind默认属性为:
{
placeholder: label || '',
clearable: true,
style: 'width: 200px'
}
时间类型的默认属性为:
{
style: 'width: 190px',
type: 'datetime',
placeholder: '请选择时间',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss'
}
childSlot
本属性为插槽名称,动态插槽渲染。
主要用于elementUI中el-select
、el-checkbox-group
、el-radio-group
等此类组件中需要声明子组件的情形,例如el-select
内部需要配置el-option
,本示例也将以el-select为例
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config">
<template #selectChildSlot>
<el-option label="2024-01-01" value="2024-01-01" />
<el-option label="2023-01-01" value="2023-01-01" />
<el-option label="2022-01-01" value="2022-01-01" />
<el-option label="2021-01-01" value="2021-01-01" />
</template>
</FormPage>
<div style="margin-left: 200px">
{{ formData }}
</div>
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: '时间',
key: 'selectDate',
type: 'select',
childSlot: 'selectChildSlot',
},
]
</script>
匹配字段设置如下
type
本属性是搜索项主要配置项,默认值为ElInput
用于各搜索项配置类型及特殊处理声明
String类型数据(除 times 与 slot )
String 类型传入type是较为常用的情景,主要是将element-UI组件标签文本传入type内,交由type进行渲染交互,对于element-UI标签可传入驼峰式或-分割,下文将使用el-input-number
标签进行演示,因el-input-number
标签文本结构较为复杂,能够清晰表达出作者对于type接收值的处理
注意:times与slot被排除在外,当文本类型无法捕获element-UI时,将使用默认的ElInput
,没有传type时也将使用ElInput
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config"/>
<div style="margin-left: 200px">
{{ formData }}
</div>
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: 'test1',
key: 'test1',
type: 'el-input-number',
},
{
label: 'test2',
key: 'test2',
type: 'el-inputNumber',
},
{
label: 'test3',
key: 'test3',
type: 'input-number',
},
{
label: 'test4',
key: 'test4',
type: 'El-Input-Number',
},
{
label: 'test5',
key: 'test5',
type: 'inputNumber',
},
{
label: 'test6',
key: 'test6',
type: 'elInputNumber',
},
{
label: 'test7',
key: 'test7',
type: 'ElInputNumber',
},
{
label: 'test8',
key: 'test8',
type: 'InputNumber',
},
]
</script>
字符串 times
当 type = ‘times’ 将会分别展示开始时间与结束时间,字段将强制设为startTime
与endTime
如:{ label: '时间', type: 'times'}
就将渲染为
接口中也将携带为
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config"/>
<div style="margin-left: 200px">
{{ formData }}
</div>
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: '时间',
type: 'times',
},
]
</script>
绑定Key
默认值分别为startKey
与endKey
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config"/>
<div style="margin-left: 200px">
{{ formData }}
</div>
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: '时间',
type: 'times',
startKey: 'startKey',
endKey: 'endKey',
},
]
</script>
默认值
默认值分别为startDefaultValue
与endDefaultValue
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config"/>
</FormPage>
<div style="margin-left: 200px">
{{ formData }}
</div>
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: '时间',
type: 'times',
startDefaultValue: '2024-01-01 00:00:00',
endDefaultValue: '2024-12-31 23:59:59',
},
]
</script>
绑定属性
默认值分别为startBind
与endBind
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config"/>
<div style="margin-left: 200px">
{{ formData }}
</div>
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: '时间',
type: 'times',
startBind: {
type: 'date',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD 00:00:00',
style: {
width: '150px',
},
},
endBind: {
type: 'date',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD 23:59:59',
style: {
width: '350px',
},
},
},
]
</script>
绑定Key
字符串 slot (及 配套 slotName 属性)
当 type =‘slot’ 时,意味着你将要对该搜索项手动处理,组件将根据你设置的slotName进行暴露插槽,便于业务处理
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config">
<template #slotModules> 插槽开发 </template>
</FormPage>
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
const formData = ref({})
const config = [
{
label: 'slot测试',
key: 'slotData',
defaultValue: 'ok',
type: 'slot',
slotName: 'slotModules',
},
{
label: 'test',
},
]
</script>
匹配流程如下
注:可以传入整个组件给type,并通过v-model
进行绑定,而无需通过插槽使用自定义组件详见 type-vue组件类型 VueComponent
vue组件类型 VueComponent
最后,type 也可以接收vue3 的相关组件,并仍可使用bind字段进行属性绑定,传入组件建议可通过v-model
进行双向绑定,因内部实现方法为modelValue
与onUpdate:modelValue
进行的v-mode
绑定,
既:自开发组件
- 满足
<componentName v-model="data">
时,即可满足其条件
为方便,作者复用elementUI的ElInput
组件作为传入组件
<template>
<div style="padding: 50px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config">
<template #slotModules> 插槽开发 </template>
</FormPage>
</div>
</template>
<script setup>
import { FormPage } from 'adminpage-vue3'
import { ref } from 'vue'
import { ElInput } from 'element-plus' //可以用你写的组件
const formData = ref({})
const config = [
{
label: '自定义组件',
key: 'DIY',
type: ElInput,
bind: {
type: 'textarea',
},
},
]
</script>
notNull 必填校验
notNull
接收布尔值,当·notNull·为true且该项未输入时,将抛出异常
<template>
<div>
<div style="padding: 10px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
<el-button type="primary" @click="validateDate">校验</el-button>
</div>
</div>
</template>
<script setup>
import { FormPage } from 'page-vue3'
const formData = ref({})
const FormPageRef = ref(null)
function validateDate() {
FormPageRef.value.validate()
}
const config = [
{
label: '输入',
key: 'input',
notNull: true,
},
]
</script>
<style lang="scss" scoped></style>
isInt整数校验(不可负数)
isInt
接收布尔值,当isInt
为true且该项输入非正整数,将抛出异常
注意:该参数不作为必填项校验,若必填校验请单独声明notNull
<template>
<div>
<div style="padding: 10px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
<el-button type="primary" @click="validateDate">校验</el-button>
</div>
</div>
</template>
<script setup>
import { FormPage } from 'page-vue3'
const formData = ref({})
const FormPageRef = ref(null)
function validateDate() {
FormPageRef.value.validate()
}
const config = [
{
label: '输入',
key: 'input',
isInt: true,
},
]
</script>
<style lang="scss" scoped></style>
isNumber 数值校验(可小数)(不可负数)
isNumber
接收布尔值或正整数,当·isNumber ·为true或Number 且该项输入非数值,将抛出异常
注意:该参数不作为必填项校验,若必填校验请单独声明notNull
不限制长度
isNumber
接收布尔值时,当isNumber
为true且该项输入非数值,将抛出异常
<template>
<div>
<div style="padding: 10px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
<el-button type="primary" @click="validateDate">校验</el-button>
</div>
</div>
</template>
<script setup>
import { FormPage } from 'page-vue3'
const formData = ref({})
const FormPageRef = ref(null)
function validateDate() {
FormPageRef.value.validate()
}
const config = [
{
label: '输入',
key: 'input',
isNumber: true,
},
]
</script>
<style lang="scss" scoped></style>
限制长度
isNumber
接收正整数时,将限制用户输入小数长度,将抛出异常
注意:此长度仅限制小数部分,整数长度不包含在内
<template>
<div>
<div style="padding: 10px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
<el-button type="primary" @click="validateDate">校验</el-button>
</div>
</div>
</template>
<script setup>
import { FormPage } from 'page-vue3'
const formData = ref({})
const FormPageRef = ref(null)
function validateDate() {
FormPageRef.value.validate()
}
const config = [
{
label: '输入',
key: 'input',
isNumber: 1,
},
]
</script>
<style lang="scss" scoped></style>
isMinusNumber 数值校验(可小数)(可负数)
isMinusNumber
接收布尔值或正整数,当·isMinusNumber ·为true或Number 且该项输入非数值,将抛出异常
注意:该参数不作为必填项校验,若必填校验请单独声明notNull
不限制长度
isMinusNumber
接收布尔值时,当isMinusNumber
为true且该项输入非数值,将抛出异常
<template>
<div>
<div style="padding: 10px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
<el-button type="primary" @click="validateDate">校验</el-button>
</div>
</div>
</template>
<script setup>
import { FormPage } from 'page-vue3'
const formData = ref({})
const FormPageRef = ref(null)
function validateDate() {
FormPageRef.value.validate()
}
const config = [
{
label: '输入',
key: 'input',
isMinusNumber: true,
},
]
</script>
<style lang="scss" scoped></style>
限制长度
isMinusNumber
接收正整数时,将限制用户输入小数长度,将抛出异常
注意:此长度仅限制小数部分,整数长度不包含在内
<template>
<div>
<div style="padding: 10px">
<FormPage ref="FormPageRef" v-model="formData" :formConfig="config" />
<el-button type="primary" @click="validateDate">校验</el-button>
</div>
</div>
</template>
<script setup>
import { FormPage } from 'page-vue3'
const formData = ref({})
const FormPageRef = ref(null)
function validateDate() {
FormPageRef.value.validate()
}
const config = [
{
label: '输入',
key: 'input',
isMinusNumber: 1,
},
]
</script>
<style lang="scss" scoped></style>