封装form 表单,根据表单的input select 类型动态封装BaseForm
<template>
<view class="container">
<BaseForm
:submitTitle="submitTitle"
:formArr="formArr"
:formData="formData"
:rules="rules"
@searchInput="searchInput"
@submit="submit"
@uploadSelect="uploadSelect"
@init="init"
></BaseForm>
</view>
</template>
<script>
import BaseForm from '@/components/baseForm/baseForm.vue';
export default {
components: { BaseForm },
data() {
return {
submitTitle: '保存',
formArr: [
{
editType: 1,
colName: '姓名',
col: 'name',
nullable: false,
dataType: '',
defaultValue: '',
tipMsg: '',
editParam: {},
maxLength: 10,
whenShow: '',
calcScript: '',
rules: [
{
required: true,
errorMessage: '姓名项必填'
},
{
maxLength: 5,
errorMessage: '姓名长度不超过 {maxLength} 个字符'
}
]
},
{
editType: 1,
colName: '年龄',
col: 'age',
nullable: true,
dataType: 'number',
defaultValue: 20,
tipMsg: '',
editParam: {},
maxLength: 10,
whenShow: '',
calcScript: ''
},
{
editType: 1,
colName: '身高',
col: 'height',
nullable: true,
dataType: 'digit',
defaultValue: '',
tipMsg: '',
editParam: {},
maxLength: 10,
whenShow: '',
calcScript: ['weight/(height*height)=bim']
},
{
editType: 1,
colName: '体重(kg)',
col: 'weight',
nullable: true,
dataType: 'digit',
tipMsg: '',
editParam: {},
maxLength: 10,
whenShow: '',
calcScript: ['weight/(height*height)=bim']
},
{
editType: 1,
colName: 'BIM',
col: 'bim',
nullable: true,
dataType: 'digit',
tipMsg: '',
editParam: {},
maxLength: 10,
whenShow: '',
calcScript: ''
},
{
editType: 1,
colName: '文本域',
col: 'text',
nullable: true,
dataType: 'textarea',
tipMsg: '',
editParam: {},
maxLength: 10,
whenShow: '',
calcScript: '',
placeholder: '',
fromNoMid: true
},
{
editType: 10,
colName: '日期时间',
col: 'date',
nullable: false,
defaultValue: '',
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: 'datetime',
rules: [
{
required: true,
errorMessage: '日期项必填'
}
]
},
{
editType: 11,
colName: '日期Darw',
col: 'darwDate',
nullable: false,
defaultValue: '',
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: 'range',
rules: [
{
required: true,
errorMessage: '日期项必填'
}
]
},
{
editType: 20,
colName: '下拉选择',
col: 'selectCol',
nullable: false,
defaultValue: '1',
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: '',
list: this.getList(),
rules: [
{
required: true,
errorMessage: '下拉选择项必填'
}
]
},
{
editType: 21,
colName: '远程搜索',
col: 'searchSelect',
nullable: false,
defaultValue: '1',
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: '',
list: this.getList(),
rules: [
{
required: true,
errorMessage: '搜索选择必填'
}
]
},
{
editType: 24,
colName: 'darw选择',
col: 'darwSelect',
nullable: false,
defaultValue: '',
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: 'selector',
defaultProps: { label: 'name', value: 'id', children: 'child' },
list: [{ id: '1', name: '男' }, { id: '2', name: '女' }],
rules: [
{
required: true,
errorMessage: '搜索选择必填'
}
]
},
{
editType: 22,
colName: '单选',
col: 'radio',
nullable: false,
defaultValue: '',
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: '',
list: this.getList(),
rules: [
{
required: true,
errorMessage: '单选项必填'
}
]
},
{
editType: 23,
colName: '复选',
col: 'chenckbox',
nullable: false,
defaultValue: '',
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: '',
list: this.getList(),
rules: [
{
required: true,
errorMessage: '复选项必填'
}
]
},
{
editType: 25,
colName: '开关',
col: 'switch',
nullable: true,
defaultValue: false,
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: ''
},
{
editType: 30,
colName: '上传',
col: 'fileUp',
nullable: true,
defaultValue: [],
tipMsg: '',
whenShow: '',
calcScript: '',
dataType: ''
}
],
// 基础表单数据
formData: {},
//规则校验
rules: {}
};
},
created() {
this.formArr.forEach(item => {
this.$set(this.formData, item.col, item.defaultValue);
if (item.rules) {
this.$set(this.rules, item.col, { rules: item.rules });
}
});
},
onReady() {
// 设置自定义表单校验规则,必须在节点渲染完毕后执行
},
methods: {
init() {
// this.formData = {};
console.log('清空');
this.formArr.forEach(item => {
this.$set(this.formData, item.col, item.defaultValue);
});
},
uploadSelect(val, item) {
console.log(val, item);
//上传文件后台接口处理
},
searchInput(val) {
console.log(val, 'val');
//查询
},
getList() {
return [
{
text: '跑步',
value: '1'
},
{
text: '游泳',
value: '2'
},
{
text: '绘画',
value: '3'
},
{
text: '足球',
value: '4'
},
{
text: '篮球',
value: '5'
}
];
},
submit(form) {
form.validate()
.then(res => {
console.log('表单数据信息:', res);
})
.catch(err => {
console.log('表单错误信息:', err);
});
}
}
};
</script>
<style lang="scss">
.example {
padding: 15px;
background-color: #fff;
}
.segmented-control {
margin-bottom: 15px;
}
.button-group {
margin-top: 15px;
display: flex;
justify-content: space-around;
}
.form-item {
display: flex;
align-items: center;
}
.button {
display: flex;
align-items: center;
height: 35px;
margin-left: 10px;
}
</style>
baseForm.vue
<template>
<view class="base-form">
<scroll-view :scroll-y="true" :style="{ height: height - 185 + 'rpx' }">
<view class="base-form-filter">
<uni-forms ref="form" :modelValue="newFormData" :rules="rules">
<uni-forms-item v-for="(item, index) in formArr" :key="item.col" :name="item.col" :label="item.colName" :required="!item.nullable">
<!--input-->
<uni-easyinput
v-if="item.editType == 1"
:type="item.dataType"
v-model="newFormData[item.col]"
:placeholder="item.placeholder ? item.placeholder : '请输入' + item.colName"
/>
<!--单选-->
<uni-data-checkbox v-if="item.editType == 22" v-model="newFormData[item.col]" :localdata="item.list" />
<!--多选-->
<uni-data-checkbox v-if="item.editType == 23" multiple v-model="newFormData[item.col]" :localdata="item.list" />
<!--日期选择(type=date/daterange/datetime/datetimerange)-->
<uni-datetime-picker v-if="item.editType == 10" :type="item.dataType" v-model="newFormData[item.col]" />
<!--日期选择darw(type=date/range/time/half)-->
<uni-date-darw-picker v-if="item.editType == 11" :type="item.dataType" v-model="newFormData[item.col]"></uni-date-darw-picker>
<!--下拉select-->
<uni-data-picker
v-if="item.editType == 20"
:type="item.dataType"
v-model="newFormData[item.col]"
:localdata="item.list"
:placeholder="item.placeholder ? item.placeholder : '请选择' + item.colName"
></uni-data-picker>
<!--远程搜索选择-->
<uni-data-select
v-if="item.editType == 21"
:candidates="item.list"
:placeholder="item.placeholder ? item.placeholder : '请选择' + item.colName"
v-model="newFormData[item.col]"
@select="onSelect"
:item="item"
@input="searchInput"
@clear="onClear"
></uni-data-select>
<!--darw(type=linkage/selector)-->
<uni-draw-picker
v-if="item.editType == 24"
:type="item.dataType"
:level="item.level"
v-model="newFormData[item.col]"
:options="item.list"
:defaultProps="item.defaultProps"
:placeholder="item.placeholder ? item.placeholder : '请选择' + item.colName"
></uni-draw-picker>
<!--switch-->
<switch v-if="item.editType == 25" :color="item.color || '#1cbbb4'" @change="switchChange($event, item)" :checked="newFormData[item.col]" />
<!--文件上传-->
<uni-file-picker v-if="item.editType == 30" v-model="newFormData[item.col]" mode="grid" @select="select($event, item)" />
</uni-forms-item>
</uni-forms>
</view>
</scroll-view>
<view class="btn-box">
<view class="reset" @click="reset">{{ cancelTitle }}</view>
<view class="submit" @click="submit">{{ submitTitle }}</view>
</view>
</view>
</template>
<script>
import UniDataSelect from '../uni-data-select/uni-data-select.vue';
import UniDateDrawPicker from '../uni-date-darw-picker/uni-date-darw-picker.vue';
import UniDrawPicker from '../uni-darw-picker/uni-draw-picker.vue';
export default {
components: { UniDataSelect, UniDateDrawPicker, UniDrawPicker },
data() {
return {
newFormData: {}
};
},
emits: ['input', 'select', 'submit', 'uploadSelect'],
props: {
formArr: {
default: () => {
return [];
}
},
formData: {
default: () => {
return {};
}
},
height: {
type: [Number, String],
default: ''
},
rules: {
default: () => {
return {};
}
},
submitTitle: {
default: () => {
return '确定';
}
},
cancelTitle: {
default: () => {
return '重置';
}
}
},
onReady() {
// 设置自定义表单校验规则,必须在节点渲染完毕后执行
this.$refs.form.setRules(this.rules);
},
watch: {
formData: {
handler(newValue, oldValue) {
this.newFormData = newValue;
},
deep: true
}
},
mounted() {
this.newFormData = this.formData;
},
computed: {},
methods: {
switchChange(e, item) {
this.$set(this.newFormData, item.col, e.detail.value);
},
onSelect(value, data, item) {
this.$set(this.newFormData, item.col, value);
},
searchInput(value) {
this.$emit('searchInput', value);
},
onClear(item) {
this.$set(this.newFormData, item.col, '');
},
// 获取上传状态
select(e, item) {
this.$emit('uploadSelect', e, item);
},
submit() {
this.$emit('submit', this.$refs.form);
},
reset() {
//初始化数据
this.formArr.forEach(item => {
this.$set(this.newFormData, item.col, item.defaultValue);
});
}
}
};
</script>
<style lang="scss" scoped>
.base-form {
background-color: #fff;
}
.base-form-filter {
padding: 0 30rpx;
padding-bottom: 180rpx;
}
.btn-box {
display: flex;
height: 160rpx;
align-items: center;
justify-content: space-between;
position: fixed;
bottom: 0;
background: #ffffff;
z-index: 9;
width: 100%;
> view {
width: 50%;
height: 80rpx;
line-height: 80rpx;
border: solid 2rpx #ec652b;
align-items: center;
justify-content: center;
text-align: center;
font-size: 30rpx;
}
.reset {
color: #ec652b;
border-radius: 20px 0px 0px 20px;
margin-left: 30rpx;
}
.submit {
color: #fff;
background-color: #ec652b;
border-radius: 0px 20px 20px 0px;
margin-right: 30rpx;
}
}
</style>
uni-data-select.vue
uni-date-darw-picker.vue
uni-draw-picker.vue
https://zh.uniapp.dcloud.io/ 组件中下载即可