uni-app表单组件

这是一个基于Vue.js的动态表单构建组件,包括输入框、数字输入、文本域、单选框、复选框、时间选择等多种表单元素,支持数据验证和自定义样式。同时,组件还提供了上传图片、文件、选择器等功能,并能与外部API交互获取选项数据。
摘要由CSDN通过智能技术生成

common-form.vue

<template>
	<view>
		<u--form :model="form" ref="uForm" :rules="rules" :labelWidth="labelWidth" labelAlign="left"  :labelPosition="labelPosition">
			<u-form-item :label="item.label" :prop="item.prop" v-for="(item) in formData" :key="item.prop" 
			 :required="item.isRule === '1'"
			 :class="item.type === 'textarea'?'labelLeft':item.type === 'wrapInput'?'warp-item':''"
			 customStyle="padding:28upx 32upx;background:#fff;margin-top:2upx;" class="form-item"
			 @click="handleFormItem(item)">
				<!-- 输入框 -->
				<u-input v-model="form[item.prop]" :inputAlign="labelPosition==='left'?'right':''" :placeholder="item.placeholder||placeholder" border="none" :type="item.isType" :disabled="item.disable" clearable v-if="item.type=='input'"/>
				<number :inputAlign="labelPosition==='left'?'right':''" v-if="item.type=='number'" :itemData="{precision:2,value:form[item.prop]}" @ok="setFormProp"/>
				<view class="u-font-28" style="text-align: right;" v-if="item.type === 'wrapInput'" v-html="form[item.prop]&&form[item.prop].replace(/,/g,'<br />')||'--'"></view>
				<!-- 文本域 -->
				<u--textarea v-model="form[item.prop]" :placeholder="item.placeholder||'请输入内容'" :confirmType="'done'" :disabled="item.disable" v-if="item.type=='textarea'" border="none" customStyle="padding:0" :height="20 * item.rows"></u--textarea>
				<textarea v-model="form[item.prop]" placeholder="请输入内容" v-if="item.type=='TextContent'" disabled="true" border="none" customStyle="padding:10upx" :height="20 * item.rows"></textarea>
				<!-- 单选框 -->
				<u-radio-group  v-model="form[item.prop]" :disabled="item.disable" v-if="item.type == 'radio'"  placement="column">
					<u-radio :label="radio.label" :name="radio.value" :class="[radioIndex!==0?'u-mt-40': 'u-mt-16','radio']" v-for="(radio,radioIndex) in item.options" :key="radio.value"></u-radio>
				</u-radio-group>
				<!-- 复选框 -->
				<u-checkbox-group
					v-model="form[item.prop]"
					placement="column"
					:disabled="item.disable"
					v-if="item.type == 'checkbox'"
					activeColor="#0054A3"
					class="checkbox-group">
					<u-checkbox
						:customStyle="{marginBottom: '8px'}"
						v-for="(item, index) in item.options"
						:key="index"
						:label="item.label"
						:name="item.value"
						class="u-mb-32"
					>
					</u-checkbox>
				</u-checkbox-group>
				
				<!-- 时间 -->
				<template v-if="isShowDate(item)">
					<!-- <u-input v-model="form[item.prop]" placeholder="请选择" border="none" clearable readonly/> -->
					<view class="u-content-color" :style="labelPosition==='left'?'text-align: right;flex: 1;':''">
						{{ translateTime(form[item.prop]) }}
					</view>
					<template v-if="!item.disable&&labelPosition==='top'">
						<u-icon
							slot="labelTop-Right"
							name="arrow-right" color="#a9a9a9" size="18" v-if="!form[item.prop] || item.disable">
						</u-icon>
						<u-icon
							slot="labelTop-Right"
							name="close-circle-fill" color="#a6a6a6" size="18" @click.native.stop="form[item.prop]=''" v-else>
						</u-icon>
					</template>
				</template>
				
				<!-- 图片 -->
				<template v-if="item.type == 'file'">
					<view v-if="labelPosition!=='left'" class="" slot="labelTop-Right" @click="uploadImage(item)">
						<u-icon name="photo" size="25" color="#363636"></u-icon>
					</view>
					<view :style="labelPosition==='left'?'flex: 1;display: flex;align-items: center;':''" class="u-rela u-mr-2" v-for="(image,index) in form[item.prop]" :key="index">
						<!-- <u--image :src="image" radius="2" width="90upx" height="90upx" @click.native.stop="previewImage(image)"></u--image> -->
						<comImage :image="image" :levelLayout="item.levelLayout||''"/>
						<!-- <view class="image-close u-flex-xy-center" @click="handleDeleteImage(item.prop,index)">
							<u-icon name="close" color="#fff" size="12"></u-icon>
						</view> -->
						<view v-if="labelPosition==='left'" @click="uploadImage(item)">
							<u-icon v-if="!item.disable" name="arrow-right" size="16" color="#363636"></u-icon>
						</view>
					</view>
				</template>
				<!-- 文件 -->
				<template v-if="item.type == 'docFile'">
					<view v-if="labelPosition!=='left'" class="" slot="labelTop-Right" @click="uploadDocFile(item)">
						<u-icon name="plus" size="22" color="#363636"></u-icon>
					</view>
					<view :style="labelPosition==='left'?'flex: 1;display: flex;align-items: center;':''" class="u-rela u-mr-2" v-for="(it,index) in form[item.prop]" :key="index">
						<view class="">
							{{it}}
						</view>
					</view>
				</template>
				
				<!-- 选择器 -->
				<template v-if="item.type == 'select'">
					<view :style="labelPosition==='left'?'text-align: right;flex: 1;':''" class="u-content-color" v-if="typeof form[item.prop] ==='string'||typeof form[item.prop] ==='number'">
						{{ translateName(item) }}
					</view>
					<!-- 多选类型的数组 -->
					<view :style="labelPosition==='left'?'text-align: right;':''" v-else v-for="(value,vIndex) in form[item.prop]" :key="vIndex" style="width:100%">
						{{ getMultiLabel(value,item) }}
					</view>
					
					<template v-if="!item.disable&&labelPosition==='top'">
						<u-icon
							slot="labelTop-Right"
							color="#a9a9a9" size="18"
							name="arrow-right" v-if="!form[item.prop]">
						</u-icon>
						<u-icon
							slot="labelTop-Right"
							size="18"
							name="close-circle-fill" color="#a6a6a6" @click.native.stop="clearValue(item)" v-else>
						</u-icon>
					</template>
				</template>
				<template v-if="item.type == 'seachSelect'">
					<view :style="labelPosition==='left'?'text-align: right;flex: 1;':''" class="u-content-color">
						{{ item.getName || form[item.editName] || '请选择' }}
					</view>
					<template v-if="!item.disable&&labelPosition==='top'">
						<u-icon
							slot="labelTop-Right"
							color="#a9a9a9" size="18"
							name="arrow-right" v-if="!form[item.prop]">
						</u-icon>
						<u-icon
							slot="labelTop-Right"
							size="18"
							name="close-circle-fill" color="#a6a6a6" @click.native.stop="clearValue(item)" v-else>
						</u-icon>
					</template>
				</template>
				<template v-if="item.type == 'seachDrugName'">
					<view :style="labelPosition==='left'?'text-align: right;flex: 1;':''" class="u-content-color">
						{{ item.drugName || form[item.editName] || '请选择' }}
					</view>
					<template v-if="!item.disable&&labelPosition==='top'">
						<u-icon
							slot="labelTop-Right"
							color="#a9a9a9" size="18"
							name="arrow-right" v-if="!form[item.prop]">
						</u-icon>
						<u-icon
							slot="labelTop-Right"
							size="18"
							name="close-circle-fill" color="#a6a6a6" @click.native.stop="clearValue(item)" v-else>
						</u-icon>
					</template>
				</template>
				
				<!-- 部门 -->
				<template v-if="item.type == 'deptTree'">
					<view class="u-content-color" >
						 {{ deptName || '请选择' }}
					</view> 
					<u-icon
						slot="labelTop-Right"
						color="#a9a9a9" size="18"
						name="arrow-right" v-if="!deptName">
					</u-icon>
					<u-icon
						slot="labelTop-Right"
						size="18"
						name="close-circle-fill" color="#a6a6a6" @click.native.stop="clearValue(item)" v-else>
					</u-icon>
				</template>

				<!-- 省市区 -->
				<template v-if="item.type == 'province'">
					<view class="u-content-color" :style="labelPosition==='left'?'text-align: right;flex: 1;':''">
						 {{ region|| form[item.editName] || '请选择' }}
					</view>
					<template v-if="!item.disable&&labelPosition==='top'">
						<u-icon
							slot="labelTop-Right"
							color="#a9a9a9" size="18"
							name="arrow-right" v-if="!region">
						</u-icon>
						<u-icon
							slot="labelTop-Right"
							size="18"
							name="close-circle-fill" color="#a6a6a6" @click.native.stop="clearProValue" v-else>
						</u-icon>
					</template>
				</template>

			</u-form-item>
		</u--form>
		
		<u-datetime-picker
			:show="dateTimeShow"
			v-model="dateTimeValue"
			:mode="dateMode"
			:minDate="minDate"
			@confirm="dateTimeConfirm"
			@cancel="dateTimeShow=false"
			:closeOnClickOverlay="true"
			@close="dateTimeShow=false"
		></u-datetime-picker>
		
		<year ref="year" @ok="setFormProp"/>
		<!-- 日期范围 -->
		<u-calendar :show="calendarShow" :monthNum="'72'" :minDate="minDate" :maxDate="maxDate" :defaultDate="defaultDate" :mode="calendarMode" :allowSameDay="true" :closeOnClickOverlay="true" @confirm="calendarConfirm" @close="calendarShow=false"></u-calendar>
		
		<lotus-address v-if="proControl" v-on:choseVal="choseValue" :lotusAddressData="lotusAddressData"></lotus-address>
		
		<actionList ref="actionList" @ok="setFormProp" @nextPage="nextPage"/>
	</view>
</template>

<script>
import actionList from './actionList.vue'
import comImage from './comImage.vue'
import number from './number.vue'
import year from '../year/year.vue'
import { dictData,updateImg } from '@/api/common.js'
import lotusAddress from "../Winglau14-lotusAddress/Winglau14-lotusAddress.vue";

export default {
	components: {
		actionList,
		comImage,
		number,
		year,
		lotusAddress
	},
	props: {
		form: {
			type: Object,
			default: () => {}
		},
		// 表达数据必填
		formData: {
			type: Array,
			default: () => [],
			required: true
		},
		rules: {
			type: Object,
			default: () => {}
		},
		// 占位符
		placeholder: {
			type: String,
			default: '请输入'
		},
		// label宽度
		labelWidth: {
			type: [String,Number],
			default: 45
		},
		// 布局方式参数
		labelPosition: {
			type: [String],
			default: 'top'
		},
	},
	computed: {
		// rules() {
		// }
	},
	watch:{
		"form":(val)=>{
		}
	},
	data() {
		return {
			value: '',
			dateTimeShow: false,
			dateTimeValue: '',
			curField: '', // 当前表单元素绑定字段
			dateMode: '', //日期模式
			deptName: null, // 部门名称
			calendarShow: false,
			calendarMode: 'single', // 日历模式 
			isLoaded: false, // 是否已加载
			lotusAddressData:{ // 省市区
				visible:false,
				provinceName:'',
				cityName:'',
				townName:'',
			},
			region:'',
			proControl:false,
			minDate:null,
			maxDate:null,
			defaultDate:null,
			getToday:''
		};
	},
	mounted() {
	    this.$refs.uForm.setRules(this.rules)
		//获取今天的日期
		var date = new Date()
		this.dateTimeValue = date.getFullYear()+'-'+(date.getMonth()<9?'0':'')+(date.getMonth()+1)+'-'+(date.getDate()<10?'0':'')+date.getDate()
		
	},
	created() {
		this.getOptions()
	},
	methods: {
		nextPage(n){
			this.$emit('nextPage',n )
		},
		//打开picker
		openPicker() {
			this.lotusAddressData.visible = true;
			this.lotusAddressData.provinceName = '';
			this.lotusAddressData.cityName = '';
			this.lotusAddressData.townName = '';
		},
		clearProValue(){
			this.region = ''
			this.form.nativePlace = ''
		},
		//回传已选的省市区的值
		choseValue(res){
			//res数据源包括已选省市区与省市区code
			console.log(res);
			this.lotusAddressData.visible = res.visible;//visible为显示与关闭组件标识true显示false隐藏
			//res.isChose = 1省市区已选 res.isChose = 0;未选
			if(res.isChose){
				this.lotusAddressData.provinceName = res.province;//省
				this.lotusAddressData.cityName = res.city;//市
				this.lotusAddressData.townName = res.town;//区
				this.region = `${res.province} ${res.city} ${res.town}`; //region为已选的省市区的值
				// this.form.nativePlace = res.provinceCode+res.cityCode+res.townCode// 籍贯
				// this.form.nativePlace = res.townCode// 籍贯(只取最后一级的code)
				// this.form.address = res.townCode// 客户管理-客户地址(只取最后一级的code)
				
				this.formData.map(item=>{
					if (item.type === 'province') {
						this.form[item.prop] = res.townCode || res.cityCode // 区是空时,取上一级的code
					}
				})
			}
		},
		async getOptions(){
			await Promise.all(
				this.formData.map(async (item)=>{
					if (item.dictType) {
						item.options = await this.getDicts(item.dictType)
						if (this.form[item.prop]) {
							this.translateName(item)
						}
					}
					if (item.type === 'province') { //省市区显示控件条件
						this.proControl = true
					}
				})
			)
		},
		// 自定义的设置最大时间、最小时间、默认时间的方法
		chooseTimed(){
			let date = new Date()
			let year = date.getFullYear()
			let month = date.getMonth() + 1
			let day = date.getDate()
			if (month <= 9) {
				month = '0' + month
			}
			if (day <= 9) {
				day = '0' + day
			}
			let minyear = year - 2
			this.minDate = minyear + '-' + month + '-' + day
			let maxyear = year + 8
			this.maxDate = maxyear + '-' + month + '-' + day
			this.defaultDate = year + '-' + month + '-' + day
		},
		// 点击表单元素
		async handleFormItem(item,index) {
			if (item.disable) {
				return
			}
			const { type,prop,label } = item
			if (item.minDate) {
				this.minDate = item.minDate || null
			}
			let dateType = {
				month: 'year-month',
				date: 'date',
				datetime: 'datetime',
			}
			// 日期
			if(dateType[type]) {
				this.dateMode = dateType[type]
				this.dateTimeShow = true
			} else if(type == 'daterange') {
				this.calendarMode = 'range'
				this.calendarShow = true
				this.chooseTimed()
			} else if(type == 'dates') {
				this.calendarMode = 'multiple'
				this.calendarShow = true
			} else if(type == 'year') {
				this.$refs.year.showPicker()
			} else if(type == 'select') {
				this.$refs.actionList.showPop(label,item.options,item.multiple)
			} else if(type == 'deptTree') {
				uni.$u.route('/pages/oaApproval/selectDept')
			}else if(type == 'seachSelect') {
				uni.$u.route('/pages/oaApproval/selectPerson',{
					isMultiple: true
				})
			}else if(type == 'seachDrugName') {
				uni.$u.route('/pages/businessTalk/selectDrug')
			} else if (type === 'province') {
				this.openPicker()
			}
			this.curField = prop
		},
		getDicts(dictType){
			return new Promise((resolve, reject)=>{
				dictData(dictType).then(res=>{
					if (res.code === 200) {
						const options = res.data.map(item => {
							return {
								dictType: item.dictType,
								label: item.dictLabel,
								value: item.dictValue
							}
						})
						resolve(options)
					}
				})
			})
			
		},
		// 上传文件
		uploadDocFile(item){
			if (item.disable) {
				return
			}
			this.$utils.uploadPhoneFile((data) => {
				if (!data||data.length<=0) {
					uni.$u.toast('上传失败!')
					return
				}
				console.log(data)
				this.form[this.curField] = [data[0].filePath]
			})
		},
		// 上传图片
		uploadImage(item) {
			if (item.disable) {
				return
			}
			this.$utils.uploadImage((data) => {
				if (!data||data.length<=0) {
					uni.$u.toast('上传失败!')
					return
				}
				if (this.curField === 'pic') { // 头像上传
					this.form[this.curField] = [data[0].filePath]
					updateImg({pic:data[0].id,id:uni.getStorageSync('userInfo').staff.id}).then(res=>{
						if (res.code === 200) {
							let userData = uni.getStorageSync('userInfo')
							userData.staff.pic = data[0].filePath
							uni.setStorageSync('userInfo', userData)
							uni.$u.toast('上传成功!')
							
						}
					})
				} else if (this.curField === 'attachObjList') { /** 需要上传附件的所有信息字段对象的情况,自定义一个picObj存储对象数据 */
					data.map(item=>{
						if (!this.form.picObj) {
							this.form.picObj = []
						}
						this.form.picObj.push(item)
					})
				} else if (this.curField === 'files') { /** 需要上传附件的所有信息字段对象的情况【智能绩效-沟通反馈】*/
					data.map(item=>{
						if (!this.form[this.curField]) {
							this.form[this.curField] = []
						}
						this.form[this.curField].push(item)
					})
				} else { //多选图片
					data.map(item=>{
						if (!this.form[this.curField]) {
							this.form[this.curField] = []
						}
						this.form[this.curField].push(item.filePath)
					})
				}
			})
		},
		// 是否显示时间控件
		isShowDate(item) {
			let dateType = ['month','date','datetime','daterange','dates','year']
			return dateType.indexOf(item.type) !== -1
		},
		// 时间确认
		dateTimeConfirm({ value }) {
			this.dateTimeShow = false
			this.form[this.curField] = this.dateMode == 'datetime' ? 
										this.$u.timeFormat(value,'yyyy-mm-dd hh:MM') 
										: this.$u.timeFormat(value,'yyyy-mm-dd')
		},
		// 时间范围
		calendarConfirm(time) {
			this.calendarShow = false
			if(this.calendarMode === 'range') {
				this.form[this.curField] = [time[0],time[time.length - 1]]
				this.$refs.uForm.validateField(this.form[this.curField]) //无法及时触发验证的问题
				//时间范围无法及时触发验证的问题
				this.rules[this.curField].validator = (rule, value, callback) => {
						if (value&&value.length>0) {
							return true
						} else {
							return false
						}
							}
				this.$forceUpdate()
				return
			}
			
			this.form[this.curField] = time
		},
		
		// 删除图片
		handleDeleteImage(prop,index) {
			this.form[prop].splice(index,1)
		},
		// 菜单选择
		actionSelect(value) {
			this.form[this.curField] = value.name
		},
		getNameFac(item) {//人员选择独立页面
			this.form[this.curField] = item.value
			this.formData.map((it,index)=>{
				if (this.curField === it.prop) {
					this.$set(this.formData[index],'getName',item.label)
				}
			})
		},
		getDrugNameFac(item) {//人员选择独立页面
			this.form[this.curField] = item.value
			this.formData.map((it,index)=>{
				if (this.curField === it.prop) {
					this.$set(this.formData[index],'drugName',item.label)
				}
			})
		},
		getMultiLabel(it,item){
			let mulData = item.options.filter(row => it === row.value)
			return mulData.length>0&&mulData[0].label || '--'
		},
		// 翻译选择器
		translateName(item) {
			let { options,prop,dictType } = item
			// 不相等说明不是同一个form-item下的元素,不能执行以下方法;解决选日期时,会清空单选的问题;
			if (this.curField||this.form[prop]) {
				let match = []
				if (prop === this.curField) {
					match = options.filter(row => row.value === this.form[this.curField])
				} else {
					match = options.filter(row => row.value === this.form[prop])
				}
				if(match.length) {
					return match[0].label
				}else {
					return item.placeholder||'请选择'
				}
			} else {
				return item.placeholder||'请选择'
			}
		},
		// 时间翻译器
		translateTime(time) {
			if(!time) { return '请选择' }
			if(Array.isArray(time)) {
				return time.join(',')
			} else {
				return time
			}
		},
		// 设置form属性值以及提示语
		setFormProp(value,tipMessage) {
			this.form[this.curField] = value
			if(tipMessage) {
				this.rules[this.curField].message = tipMessage
			}
			this.$refs.uForm.validateField(this.curField) //无法及时触发验证的问题
			this.$forceUpdate()
		},
		clearValue(item) {
			this.form[item.prop]=''
			this.deptName = null
			this.getName = null
			this.drugName = null
			this.$forceUpdate()
		},
		
		// 校验
		validate() {
			return this.$refs.uForm.validate()
		}
	},
};
</script>
<style lang="scss" scoped>
	.form-item {
		& ::v-deep .u-form-item__body__right__message {
			// background: #f9eae4;
			padding: 6upx 0 6upx 32upx;
			color: #e93f32;
			font-size: 11px;
		}
		& ::v-deep .u-form-item__body__left__content__required {
			font-size: 14px;
			/* #ifdef H5 */
				top: 0;
			/* #endif */
		}
		
		& ::v-deep .u-form-item__body__left__content__label {
			font-size: 32upx;
		}
		& ::v-deep .u-form-item__body__left {
			// width: 100%!important;
			width: auto!important;
		}
		
		& ::v-deep .u-form-item__body__right__content__slot {
			flex-wrap: wrap;
		}
		
	}
	.warp-item {
		& ::v-deep .u-form-item__body__right__content {
			align-self: flex-end;
		}
	}
	.labelLeft{
		& ::v-deep .u-form-item__body {
			flex-direction: column!important;
		}
	}
	.checkbox-group {
		width: 100%;
		& ::v-deep .u-checkbox-label--left {
			margin-bottom: 0;
			padding-top: 16upx; 
		}
		& ::v-deep .u-checkbox-label--left text {
			width: 100%;
			padding: 28upx 10upx;
			border-bottom: 1upx solid #ccc;
		}
		& ::v-deep .uicon-checkbox-mark{
			padding: 0!important;
			border-bottom: none!important;
		}
	}
	.image-close {
		width: 35upx;
		height: 35upx;
		border-radius: 50%;
		position: absolute;
		right: -12upx;
		top: -12upx;
		background: #1c1f21;
	}
	.radio {
		& ::v-deep .u-radio__text {
			width: 100%;
			padding: 28upx 10upx;
			border-bottom: 1upx solid #ccc;
		}
	}
</style>

actionList.vue

<template>
	<view class="">
		<u-popup :show="show" @close="close" @open="open" round="10">
			<view>
				<view class="u-flex u-py-16 u-border-bottom u-px-32 u-flex-items-center">
					<u-icon name="close" size="16" @click="show = false"></u-icon>
					<view style="width: 100%;" class="text-center u-bold u-font-28">请选择</view>
					<u-button type="primary" text="确定" shape="circle" customStyle="width:170upx;height:58upx;" v-if="multiple" @click="handleMultiple"></u-button>
				</view>
				<view style="width: 100%;margin: auto;" v-if="title === '所属项目'">
					<u-search placeholder="搜索" v-model="keyWord" @change="getSeach()" :showAction="false" bgColor="#f5f5f7" shape="square" height="40" class="u-mb-16" :inputStyle="{fontSize: '30upx'}" searchIconSize="24"></u-search>
				</view>
				<view class="u-px-32 u-pt-16">
					<!-- 多选 -->
					<template v-if="multiple">
						<scroll-view :scroll-top="0" scroll-y="true" style="max-height: 600upx;">
							<u-checkbox-group
								v-model="checkboxValue"
								placement="column"
								activeColor="#0054A3"
								shape="circle"
								class="checkbox"
							>
								<u-checkbox
									:customStyle="{marginBottom: '8px'}"
									v-for="(item, index) in checkboxList"
									:key="index"
									:label="item.label"
									:name="item.value"
								>
								</u-checkbox>
							</u-checkbox-group>
						</scroll-view>
					</template>
					<!-- 单选 -->
					<template v-else>
						<scroll-view :scroll-top="0" scroll-y="true" style="max-height: 600upx;" @scrolltolower="scrolltolower">
						 <u-radio-group
						    v-model="radioValue"
						    placement="column"
							activeColor="#0054A3"
						  >
						    <u-radio
						      :customStyle="{marginBottom: '8px'}"
						      v-for="(item, index) in options"
						      :key="index"
						      :label="item.fname?item.fname+'-'+item.label:item.label"
						      :name="item.value"
						      @change="radioChange"
							  class="radio"
						    >
						    </u-radio>
						  </u-radio-group> 
						</scroll-view>
					</template>
				</view>
			</view>
		</u-popup>
	</view>
</template>

<script>
	export default {
		data() {
			return {
			  show: false,
				// 基本案列数据
			  options: [],
			  oldDataList: [],//暂存源数据
			  // u-radio-group的v-model绑定的值如果设置为某个radio的name,就会被默认选中
			  radioValue: '',
			  title: '',
			  checkboxValue:[],
			  // 基本案列数据
			  checkboxList: [],
			  multiple: false, // 是否多选
			  selectPage:1,
			  keyWord:''
			}
		},
		methods: {
			changeOp(options){
				// this.options = options
			},
			scrolltolower(){
				// console.log('触底了哦')
				// console.log(this.title)
				// let params = {selectPage:this.selectPage,keyWord:this.keyWord,name:this.title}
				// if ( this.title === '药品名称') {
				// 	this.selectPage++
				// 	this.$emit('nextPage',params)
				// }
			},
			getSeach(){ //在固定数据条件下,前端做的筛选搜索
				// let params = {selectPage:1,keyWord:this.keyWord,name:this.title}
				// this.$emit('nextPage',params)
				let _search = this.keyWord
				if (_search) {
					var reg = new RegExp(_search, 'ig')
					const list = this.oldDataList.filter(function(e) {
					  return e.label.match(reg)
					})
					this.options = list
				  } else {
					this.options = this.oldDataList
				  }
			},
			showPop(label,options,multip) {
				if (multip) {
					this.multiple = multip
					this.checkboxList = options
					this.show = true
				} else {
					this.multiple = false
					this.selectPage = 1
					this.radioValue = ''
					this.title = label
					this.options = options
					this.oldDataList = options
					this.show = true
				}
				
			},
			open() {
			},
			close() {
				this.selectPage = 1
				this.show = false
				this.keyWord = ''
			},
			radioChange(value) {
				this.show = false
				this.$emit('ok',value)
			},
			handleMultiple() {
				this.show = false
				this.$emit('ok',this.checkboxValue )
			}
		}
	}
</script>

<style lang="scss" scoped>
	.radio {
		& ::v-deep .u-radio__text {
			width: 100%;
			padding: 28upx 10upx;
			border-bottom: 1upx solid #ccc;
			// border-bottom-width: 0.5px!important;
			// border-color: $u-border-color!important;
			// border-bottom-style: solid;
		}
	}
	
	.u-radio-group {
		padding: 0 16upx;
	}
	
	.checkbox {
		& ::v-deep .u-checkbox-label--left text {
			width: 100%;
			padding: 26upx 0;
		}
	}
	
</style>

comImage.vue

<template>
    <view style="width:100%;">
        <u--image :levelLayout="levelLayout" :src="filePath" radius="2" width="90upx" height="90upx" @click.native.stop="previewImage(image)"></u--image>
    </view>
</template>

<script>
	import { querryFilePath } from '@/api/approval.js'
    export default {
        props: {
            image: {
                type: String,
                default: ''
            },
			levelLayout: {
                type: String,
                default: ''
            },
        },
        data() {
            return {
				filePath: ''
            }
        },
		watch: {
			image: {
				handler(newVal) {
					if (newVal) {
						this.getPath()
					}
				},
				immediate: true
			}
		},
		methods: {
			async getPath(){
				if (this.image instanceof Object) {
					this.filePath = this.image.filePath
				}else if (this.image.indexOf('.') !== -1) {
					this.filePath = this.image
				} else {
					const obj = await querryFilePath({fileId:this.image})
					this.filePath = obj.data&&obj.data.length>0&&obj.data[0].filePath
				}
			},
			// 预览图片
			previewImage(images) {
				// 预览图片
				this.$utils.previewImage(null,images)
			},
		},
    }
</script>

<style lang="scss" scoped>

</style>

number.vue

<template>
    <view style="width:100%">
        <u-input v-model="value" :inputAlign="inputAlign" placeholder="请输入" border="none" clearable type="number" @change="confirm" @confirm="confirm"/>
    </view>
</template>

<script>
    export default {
        props: {
            // 
            itemData: {
                type: Object,
                default: () => {}
            },
			inputAlign: {
				type: String,
				default: ''
			},
        },
		watch:{
			'itemData':{
				handler(newVal) {
					let { precision,value } = newVal
					this.value = value.toFixed(precision)
				},
				deep: true
			}
		},
        created () {
			// let { precision,value } = this.itemData
			// this.value = value.toFixed(precision)
        },
        data() {
            return {
                value: null
            }
        },
		methods: {
			confirm() {
				let value = Number(this.value)
				let { max,min,tipMessage,precision } = this.itemData
				let tip = value >  max ? `不能超过${max}` : value <  min ? `不能小于${min}` : tipMessage
				this.$emit('ok',Number(Number(this.value).toFixed(precision)),tip)
			}
		},
    }
</script>

<style lang="scss" scoped>

</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值