vant移动端 封装表单

<template>
	<div class="system">
		<div class="cell-ul">
			<van-form validate-first ref='form' class="cell-form">
				<span v-for="item in options" :key="item.key">
					<van-cell-group inset :class="item.type == 'textarea' ? 'textareaVant': ''">
						<!-- 文本框 -->
						<van-field v-if="item.type === 'text'" v-model="form[item.key]" :label="item.title"
							:rules="rules[item.key]" :maxlength="item.lth" :required="item.required"
							:disabled="item.disabled"
							:placeholder="item.placeholder ? item.placeholder : '请输入' + item.title" />
						<!-- 文本域 -->
						<van-field v-if="item.type === 'textarea'" v-model="form[item.key]" rows="10" autosize
							:rules="rules[item.key]"
							:placeholder="item.placeholder ? item.placeholder : '请输入' + item.title" :label="item.title"
							:disabled="item.disabled" type="textarea" :maxlength="item.lth"
							class="text" :required="item.required"/>
						<!-- 单选下拉框 -->
						<van-cell :title="item.title" is-link @click="showPickerFn(item)" v-if="item.type === 'select'"
						:required="item.required">
							<span
								v-if="form[item.key] &&  form[item.key].indexOf('请选择') == -1">{{ form[item.key] }}</span>
							<van-field v-model="form[item.key]" :rules="rules[item.key]" class="van-disabled" v-else
								:placeholder="item.placeholder ? item.placeholder : '请选择' + item.title" disabled />
						</van-cell>
						<!-- 不可编辑 -->
						<van-cell :title="item.title"  v-if="item.type == 'edit'"
						:required="item.required">
							<span>{{form[item.setType]}}</span>
						</van-cell>
						<!-- 年月日 -->
						<van-cell v-if="item.type === 'dateNo'" :title="item.title" is-link
							@click="dateValueFn(item.key)" :required="item.required">
							<span style="margin-right: 10px;" :style="{color:!typePage ? '#0179FF' : ''}"
								v-if="form[item.key] &&  form[item.key].indexOf('请选择') == -1">{{ form[item.key] }}</span>
							<van-field v-model="form[item.key]" :rules="rules[item.key]" class="van-disabled" v-else
								:placeholder="item.placeholder ? item.placeholder : '请选择' + item.title" disabled />
						</van-cell>
						<!-- 下拉框多选 -->
						<van-cell :title="item.title" is-link @click="showPickerFn(item)" v-if="item.type === 'selectMult'"
						:required="item.required">
							<span
								v-if="form[item.key] &&  form[item.key].indexOf('请选择') == -1">{{ form[item.key] }}</span>
							<van-field v-model="form[item.key]" :rules="rules[item.key]" class="van-disabled" v-else
								:placeholder="item.placeholder ? item.placeholder : '请选择' + item.title" disabled />
						</van-cell>
						<van-cell v-if="item.type === 'upload'" :title="item.title" :required="item.required" class="cell-upload">
						<upload @uploadListFn="uploadListFn" v-model="form[item.key]" v-if="item.type === 'upload'" :accept='item.accept' :listType="item.listType"
							:limit='10' :size='10' />
							<p style="color: #999999;"  v-if="item.type === 'upload'">{{item.describe}}</p>
						</van-cell>
					</van-cell-group>
				</span>
			</van-form>
			<van-popup v-model="showDateicker" position="bottom">
				<van-datetime-picker v-model="currentDate" type="date" title="选择时间" @confirm="onDateConfirm"
					@cancel="onCancelTime" />
			</van-popup>
			<van-popup v-model="showSelect" :value="true" position="bottom"
				:style="{ height: '60%' }">
				<div class="flexBox" style="height:44px;line-height:44px;">
					<van-button class="borderBtn" style="color:#969799;" @click="showSelect=false" size="normal">关闭</van-button>
					<van-button class="borderBtn" style="color:#6398fb;" @click="define" size="normal">确认</van-button>
				</div>
				<van-checkbox-group ref="checkboxGroup" v-model="checkedValue">
					<van-cell-group>
						<van-cell v-for="(item, index) in publicData.columns" clickable :key="index"
							:title="item[publicData.label]">
							<template #right-icon>
								<van-checkbox :name="item.dictLabel" ref="checkboxes" shape="square" />
							</template>
						</van-cell>
					</van-cell-group>
				</van-checkbox-group>
			</van-popup>
			<van-action-sheet v-model="showPicker" :title="publicData.titleLabel" @cancel="onCancel">
				<div class="messageTypeBox">
					<div :class="form[publicData.key] == item[publicData.label]?'messageType messageTypeAct':'messageType'"
						v-for="(item,index) in publicData.columns" :key="index" @click="selectType(item)">
						{{item[publicData.label]}}
						<van-icon name="success" v-if="form[publicData.key] == item[publicData.label]" size="28" />
					</div>
				</div>
			</van-action-sheet>
			<div class="footerBox">
				<van-button type="default" v-if="typePage" class="footerBtn" @click="onDetele">取消
				</van-button>
				<van-button color="#0179FF" class="footerBtn" :style="{width: typePage ? '49%' : '100%' }" @click="onClickPass">确认
				</van-button>
			</div>
		</div>
	</div>
</template>

<script>
	import upload from './upload';
	export default {
		name: 'addEdit',
		props: {
			rules: {
				type: Object,
				default: function() {
					return {};
				}
			},
			options: {
				type: Array,
				default: function() {
					return [];
				}
			},
			typePage: {
				type: Boolean,
				default: function() {
					return false;
				}
			},
			form: {
				type: Object,
				default: function() {
					return {};
				}
			}
		},
		data() {
			return {
				currentDate: new Date(),
				showDateicker: false,
				timeValue: '',
				publicData: {},
				showPicker: false,
				showSelect: false,
				checkedValue: []
			}
		},
		components: {upload},
		methods: {
			onCancelTime() {
				this.showDateicker = false
			},
			onCancel() {
				this.showPicker = false;
			},
			dateValueFn(key) {
				this.timeValue = key
				this.showDateicker = true
			},
			define(){
				let arr = []
				if(this.checkedValue.length>0){
				    this.checkedValue.forEach(d=>{
				      arr.push(d)
				    })
				  }
				this.form[this.publicData.key] = arr.join('、')
					this.showSelect = false
			},
			showPickerFn(t) {
				this.publicData = {
					titleLabel: t.title,
					columns: t.option.data,
					value: t.option.props.value,
					label: t.option.props.label,
					key: t.key
				}
				if (t.multiple) {
					if (this.form[t.key] != undefined){
						let arr = []
						arr = this.form[t.key].split('、')
						this.checkedValue = arr;
					}
					this.showSelect= true;
				} else {
					this.showPicker = true;
				}
			},
			uploadListFn(v) {
				this.form.attachList = v
			},
			selectType(item) {
				this.showPicker = false;
				this.form[this.publicData.key] = item[this.publicData.label]
				this.$emit('selectChange', this.publicData, item.dictValue)
			},
			onDateConfirm(val) {
				this.form[this.timeValue] = this.processingDate(val)
				this.showDateicker = false
			},
			processingDate(date) {
				let y = date.getFullYear()
				let m = date.getMonth() + 1
				m = m < 10 ? ('0' + m) : m
				let d = date.getDate()
				d = d < 10 ? ('0' + d) : d
				let h = date.getHours()
				h = h < 10 ? ('0' + h) : h
				let M = date.getMinutes()
				M = M < 10 ? ('0' + M) : M
				let s = date.getSeconds()
				s = s < 10 ? ('0' + s) : s
				return y + '-' + m + '-' + d;
			},
			onDetele() { // 取消
			// this.$router.replace('/vehicleList/'+ this.$route.params.type)
			this.$router.go(-1)
			},
			//确定
			onClickPass() {
				this.$refs.form.validate().then(() => {
					this.submitOk(this.form)
				}).catch(() => {
					this.$toast.fail('提交失败')
				})
			},
			submitOk(form) {
				this.$emit('submitOk', this.form)
			}
		}
	}
</script>

<style scoped lang="less">
	.system {
		.cell-ul {
			padding: 30px;

			.van-cell-group--inset {
				margin: 0 0 20px
			}
		}
	}

	.van-disabled {
		padding: 0;
		background-color: transparent;
	}

	/deep/.van-field__control {
		text-align: right;
	}

	.messageTypeBox {
		padding: 0px 32px 32px;
		box-sizing: border-box;
	}

	.messageType {
		font-size: 28px;
		color: #323233;
		margin-top: 40px;
		display: flex;
		align-items: center;
		justify-content: space-between;
	}

	.messageTypeAct {
		color: #0179FF;
	}
	.footerBtn{
		width:49%;
	}
	.footerBox{
		display: flex;
		justify-content: space-between;
		width: 92%;
		height: 120px;
		padding-top: 14px;
		padding-bottom: 20px;
		position: fixed;bottom: 0;
		background-color: #F7F8FA;
	}
	.cell-form{
		padding-bottom: 120px;
	}
	.cell-upload{
		display: inline-block;
		.van-cell__value{
			margin-top: 20px;
			text-align: left;
		}
	}
	.flexBox{
		display: flex;justify-content: space-between;
		.borderBtn{
			border:none;
		}
	}
	/deep/.textareaVant .van-cell{
		display: block;
		.van-field__control{
			text-align: left;
		}
	}
	/deep/.van-field__label{
		width: 4.2rem
	}
</style>

传数据
this.options = [{
						title: '下拉框',
						key: 'selectId',
						type: 'select',
						required: true,
						setType: 'plateNumber',
						option: {
							data: [],
							props: {
								value: 'id',
								label: 'label'
							}
						}
					},
					{
						title: '下拉框多选',
						key: 'selectMultId',
						type: 'selectMult',
						multiple: true,
						required: true,
						option: {
							data: [],
							props: {
								value: 'value',
								label: 'label'
							}
						}
					},
					{
						title: '必填文本',
						key: 'requiredText',
						type: 'text',
						lth: 10,
						required: true,
						placeholder: '请输入文本'
					},
					{
						title: '文本',
						key: 'text',
						type: 'text',
						lth: 10,
						required: true
					},
					{
						title: '日期',
						key: 'date',
						type: 'dateNo',
						required: true
					},
					{
						title: '附件',
						key: 'attachList',
						type: 'upload',
						describe: '(上传文件备注)'
					},
					{
						title: '备注',
						key: 'remark',
						type: 'textarea',
						lth: 255
					}
				];
				this.rulesIn = {
					requiredText: [{
							required: true,
							trigger: 'onBlur'
						},
						{
							pattern: /^[0-9]*[1-9][0-9]*$/,
							message: '请输入正整数',
							trigger: 'onBlur'
						}
					],
					date: [{
						required: true,
						trigger: 'onBlur'
					}]
				}
				   getType(['test']).then(res => {
				     this.options[1].option.data = res.data;
				   });

你可能感兴趣的:(封装,javascript,html,css)