uni-app封装form 表单

封装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/ 组件中下载即可
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leo_5210

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值