uni-app表单组件

common-form.vue

javascript 复制代码
<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

javascript 复制代码
<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

javascript 复制代码
<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

javascript 复制代码
<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>
相关推荐
passerby606143 分钟前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
万物得其道者成2 小时前
UniApp 多端滑块验证码插件 zxj-slide-verify 实用指南
uni-app