uni-app表单组件

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,'
')||'--'"
></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>

你可能感兴趣的:(uni-app,前端)