| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 | <template>	<view class="uni-forms-item" :class="{ 'uni-forms-item--border': border, 'is-first-border': border && isFirstBorder, 'uni-forms-item-error': msg }">		<view class="uni-forms-item__box">			<view class="uni-forms-item__inner" :class="['is-direction-' + labelPos]">				<view class="uni-forms-item__label" :style="{ width: labelWid , justifyContent: justifyContent }">					<slot name="label">						<text v-if="required" class="is-required">*</text>						<uni-icons v-if="leftIcon" class="label-icon" size="16" :type="leftIcon" :color="iconColor" />						<text class="label-text">{{ label }}</text>						<view v-if="label" class="label-seat"></view>					</slot>				</view>				<view class="uni-forms-item__content" :class="{ 'is-input-error-border': msg }"><slot></slot></view>			</view>			<view				v-if="msg"				class="uni-error-message"				:class="{ 'uni-error-msg--boeder': border }"				:style="{					paddingLeft: labelLeft				}"			>				<text class="uni-error-message-text">{{ showMsg === 'undertext' ? msg : '' }}</text>			</view>		</view>	</view></template><script>/** * Field 输入框 * @description 此组件可以实现表单的输入与校验,包括 "text" 和 "textarea" 类型。 * @tutorial https://ext.dcloud.net.cn/plugin?id=21001 * @property {Boolean} 	required 			是否必填,左边显示红色"*"号(默认false) * @property {String} validateTrigger = [bind|submit]	校验触发器方式 默认 submit 可选 * 	@value bind 	发生变化时触发 * 	@value submit 	提交时触发 * @property {String } 	leftIcon 			label左边的图标,限 uni-ui 的图标名称 * @property {String } 	iconColor 			左边通过icon配置的图标的颜色(默认#606266) * @property {String } 	label 				输入框左边的文字提示 * @property {Number } 	labelWidth 			label的宽度,单位px(默认65) * @property {String } 	labelAlign = [left|center|right] label的文字对齐方式(默认left) * 	@value left		label 左侧显示 * 	@value center	label 居中 * 	@value right	label 右侧对齐 * @property {String } 	labelPosition = [top|left] label的文字的位置(默认left) * 	@value top	顶部显示 label * 	@value left	左侧显示 label * @property {String } 	errorMessage 		显示的错误提示内容,如果为空字符串或者false,则不显示错误信息 * @property {String } 	name 				表单域的属性名,在使用校验规则时必填 */export default {	name: 'uniFormsItem',	props: {		// 自定义内容		custom: {			type: Boolean,			default: false		},		// 是否显示报错信息		showMessage: {			type: Boolean,			default: true		},		name: String,		required: Boolean,		validateTrigger: {			type: String,			default: ''		},		leftIcon: String,		iconColor: {			type: String,			default: '#606266'		},		label: String,		// 左边标题的宽度单位px		labelWidth: {			type: [Number, String],			default: ''		},		// 对齐方式,left|center|right		labelAlign: {			type: String,			default: ''		},		// lable的位置,可选为 left-左边,top-上边		labelPosition: {			type: String,			default: ''		},		errorMessage: {			type: [String, Boolean],			default: ''		},		// 表单校验规则		rules: {			type: Array,			default() {				return [];			}		}	},	data() {		return {			errorTop: false,			errorBottom: false,			labelMarginBottom: '',			errorWidth: '',			errMsg: '',			val: '',			labelPos: '',			labelWid: '',			labelAli: '',			showMsg: 'undertext',			border: false,			isFirstBorder: false,			isArray: false,			arrayField: ''		};	},	computed: {		msg() {			return this.errorMessage || this.errMsg;		},		fieldStyle() {			let style = {};			if (this.labelPos == 'top') {				style.padding = '0 0';				this.labelMarginBottom = '6px';			}			if (this.labelPos == 'left' && this.msg !== false && this.msg != '') {				style.paddingBottom = '0px';				this.errorBottom = true;				this.errorTop = false;			} else if (this.labelPos == 'top' && this.msg !== false && this.msg != '') {				this.errorBottom = false;				this.errorTop = true;			} else {				// style.paddingBottom = ''				this.errorTop = false;				this.errorBottom = false;			}			return style;		},		// uni不支持在computed中写style.justifyContent = 'center'的形式,故用此方法		justifyContent() {			if (this.labelAli === 'left') return 'flex-start';			if (this.labelAli === 'center') return 'center';			if (this.labelAli === 'right') return 'flex-end';		},		labelLeft(){			return (this.labelPos === 'left' ? parseInt(this.labelWid) : 0) + 'px'		}	},	watch: {		validateTrigger(trigger) {			this.formTrigger = trigger;		}	},	created() {		this.form = this.getForm();		this.group = this.getForm('uniGroup');		this.formRules = [];		this.formTrigger = this.validateTrigger;		// 处理 name,是否数组		if (this.name && this.name.indexOf('[') !== -1 && this.name.indexOf(']') !== -1) {			this.isArray = true;			this.arrayField = this.name			// fix by mehaotian 修改不修改的情况,动态值不检验的问题			this.form.formData[this.name] = this.form._getValue(this.name, '')		}	},	mounted() {		if (this.form) {			this.form.childrens.push(this);		}		this.init();	},	// #ifndef VUE3	destroyed() {		if(this.__isUnmounted) return		this.unInit()	},	// #endif	// #ifdef VUE3	unmounted(){		this.__isUnmounted = true		this.unInit()	},	// #endif	methods: {		init() {			if (this.form) {				let { formRules, validator, formData, value, labelPosition, labelWidth, labelAlign, errShowType } = this.form;				this.labelPos = this.labelPosition ? this.labelPosition : labelPosition;				if(this.label){					this.labelWid = (this.labelWidth ? this.labelWidth : (labelWidth||70))				}else{					this.labelWid =( this.labelWidth ? this.labelWidth : (labelWidth||'auto'))				}				if(this.labelWid && this.labelWid !=='auto') {					this.labelWid +='px'				}				this.labelAli = this.labelAlign ? this.labelAlign : labelAlign;				// 判断第一个 item				if (!this.form.isFirstBorder) {					this.form.isFirstBorder = true;					this.isFirstBorder = true;				}				// 判断 group 里的第一个 item				if (this.group) {					if (!this.group.isFirstBorder) {						this.group.isFirstBorder = true;						this.isFirstBorder = true;					}				}				this.border = this.form.border;				this.showMsg = errShowType;				let name = this.isArray ? this.arrayField : this.name;				if(!name) return				if (formRules && this.rules.length > 0) {					if (!formRules[name]) {						formRules[name] = {							rules: this.rules						}					}					validator.updateSchema(formRules);				}				this.formRules = formRules[name] || {};				this.validator = validator;			} else {				this.labelPos = this.labelPosition || 'left';				this.labelWid = this.labelWidth || 65;				this.labelAli = this.labelAlign || 'left';			}		},		unInit(){			if (this.form) {				this.form.childrens.forEach((item, index) => {					if (item === this) {						this.form.childrens.splice(index, 1)						delete this.form.formData[item.name]					}				})			}		},		/**		 * 获取父元素实例		 */		getForm(name = 'uniForms') {			let parent = this.$parent;			let parentName = parent.$options.name;			while (parentName !== name) {				parent = parent.$parent;				if (!parent) return false;				parentName = parent.$options.name;			}			return parent;		},		/**		 * 移除该表单项的校验结果		 */		clearValidate() {			this.errMsg = '';		},		/**		 * 子组件调用,如 easyinput		 * @param {Object} value		 */		setValue(value) {			let name = this.isArray ? this.arrayField : this.name;			if (name) {				if (this.errMsg) this.errMsg = '';				// 给组件赋值				this.form.formData[name] = this.form._getValue(name, value);				if (!this.formRules || (typeof this.formRules && JSON.stringify(this.formRules) === '{}')) return;				this.triggerCheck(this.form._getValue(this.name, value));			}		},		/**		 * 校验规则		 * @param {Object} value		 */		async triggerCheck(value,formTrigger) {			let promise = null;			this.errMsg = '';			// fix by mehaotian 解决没有检验规则的情况下,抛出错误的问题			if (!this.validator || Object.keys(this.formRules).length === 0) return;			const isNoField = this.isRequired(this.formRules.rules || []);			let isTrigger = this.isTrigger(this.formRules.validateTrigger, this.validateTrigger, this.form.validateTrigger);			let result = null;			if (!!isTrigger || formTrigger) {				let name = this.isArray ? this.arrayField : this.name;				result = await this.validator.validateUpdate(					{						[name]: value					},					this.form.formData				);			}			// 判断是否必填,非必填,不填不校验,填写才校验			if (!isNoField && (value === undefined || value === '')) {				result = null;			}			const inputComp = this.form.inputChildrens.find(child => child.rename === this.name);			if ((isTrigger || formTrigger) && result && result.errorMessage) {				if (inputComp) {					inputComp.errMsg = result.errorMessage;				}				if (this.form.errShowType === 'toast') {					uni.showToast({						title: result.errorMessage || '校验错误',						icon: 'none'					});				}				if (this.form.errShowType === 'modal') {					uni.showModal({						title: '提示',						content: result.errorMessage || '校验错误'					});				}			} else {				if (inputComp) {					inputComp.errMsg = '';				}			}			this.errMsg = !result ? '' : result.errorMessage;			// 触发validate事件			this.form.validateCheck(result ? result : null);			// typeof callback === 'function' && callback(result ? result : null);			// if (promise) return promise			return result ? result : null;		},		/**		 * 触发时机		 * @param {Object} event		 */		isTrigger(rule, itemRlue, parentRule) {			let rl = true;			//  bind  submit			if (rule === 'submit' || !rule) {				if (rule === undefined) {					if (itemRlue !== 'bind') {						if (!itemRlue) {							return parentRule === 'bind' ? true : false;						}						return false;					}					return true;				}				return false;			}			return true;		},		// 是否有必填字段		isRequired(rules) {			let isNoField = false;			for (let i = 0; i < rules.length; i++) {				const ruleData = rules[i];				if (ruleData.required) {					isNoField = true;					break;				}			}			return isNoField;		}	}};</script><style lang="scss" >.uni-forms-item {	position: relative;	padding: 0px;	text-align: left;	color: #333;	font-size: 14px;	// margin-bottom: 22px;}.uni-forms-item__box {	position: relative;}.uni-forms-item__inner {	/* #ifndef APP-NVUE */	display: flex;	/* #endif */	// flex-direction: row;	// align-items: center;	padding-bottom: 22px;	// margin-bottom: 22px;}.is-direction-left {	flex-direction: row;}.is-direction-top {	flex-direction: column;}.uni-forms-item__label {	/* #ifndef APP-NVUE */	display: flex;	flex-shrink: 0;	box-sizing: border-box;	/* #endif */	flex-direction: row;	align-items: center;	width: 65px;	// line-height: 2;	// margin-top: 3px;	padding: 5px 0;	height: 36px;	// margin-right: 5px;	.label-text {		font-size: 13px;		color: #666666;	}	.label-seat {		margin-right: 5px;	}}.uni-forms-item__content {	/* #ifndef APP-NVUE */	width: 100%;	box-sizing: border-box;	min-height: 36px;	/* #endif */	flex: 1;}.label-icon {	margin-right: 5px;	margin-top: -1px;}// 必填.is-required {	// color: $uni-color-error;	color: #dd524d;	font-weight: bold;}.uni-error-message {	position: absolute;	bottom: 0px;	left: 0;	text-align: left;}.uni-error-message-text {	line-height: 22px;	color: #dd524d;	font-size: 12px;}.uni-error-msg--boeder {	position: relative;	bottom: 0;	line-height: 22px;}.is-input-error-border {	border-color: #dd524d;}.uni-forms-item--border {	margin-bottom: 0;	padding: 10px 0;	// padding-bottom: 0;	border-top: 1px #eee solid;	.uni-forms-item__inner {		padding: 0;	}}.uni-forms-item-error {	// padding-bottom: 0;}.is-first-border {	/* #ifndef APP-NVUE */	border: none;	/* #endif */	/* #ifdef APP-NVUE */	border-width: 0;	/* #endif */}.uni-forms--no-padding {	padding: 0;}</style>
 |