From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 15 七月 2025 11:46:57 +0800
Subject: [PATCH] 项目初始化

---
 uni_modules/uview-ui/components/u-form/u-form.vue |  214 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 214 insertions(+), 0 deletions(-)

diff --git a/uni_modules/uview-ui/components/u-form/u-form.vue b/uni_modules/uview-ui/components/u-form/u-form.vue
new file mode 100644
index 0000000..fe2dde2
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-form/u-form.vue
@@ -0,0 +1,214 @@
+<template>
+	<view class="u-form">
+		<slot />
+	</view>
+</template>
+
+<script>
+	import props from "./props.js";
+	import Schema from "../../libs/util/async-validator";
+	// 鍘婚櫎璀﹀憡淇℃伅
+	Schema.warning = function() {};
+	/**
+	 * Form 琛ㄥ崟
+	 * @description 姝ょ粍浠朵竴鑸敤浜庤〃鍗曞満鏅紝鍙互閰嶇疆Input杈撳叆妗嗭紝Select寮瑰嚭妗嗭紝杩涜琛ㄥ崟楠岃瘉绛夈��
+	 * @tutorial https://www.uviewui.com/components/form.html
+	 * @property {Object}						model			褰撳墠form鐨勯渶瑕侀獙璇佸瓧娈电殑闆嗗悎
+	 * @property {Object | Function | Array}	rules			楠岃瘉瑙勫垯
+	 * @property {String}						errorType		閿欒鐨勬彁绀烘柟寮忥紝瑙佷笂鏂硅鏄� ( 榛樿 message )
+	 * @property {Boolean}						borderBottom	鏄惁鏄剧ず琛ㄥ崟鍩熺殑涓嬪垝绾胯竟妗�   ( 榛樿 true 锛�
+	 * @property {String}						labelPosition	琛ㄥ崟鍩熸彁绀烘枃瀛楃殑浣嶇疆锛宭eft-宸︿晶锛宼op-涓婃柟 ( 榛樿 'left' 锛�
+	 * @property {String | Number}				labelWidth		鎻愮ず鏂囧瓧鐨勫搴︼紝鍗曚綅px  ( 榛樿 45 锛�
+	 * @property {String}						labelAlign		lable瀛椾綋鐨勫榻愭柟寮�   ( 榛樿 鈥榣eft' 锛�
+	 * @property {Object}						labelStyle		lable鐨勬牱寮忥紝瀵硅薄褰㈠紡
+	 * @example <u--formlabelPosition="left" :model="model1" :rules="rules" ref="form1"></u--form>
+	 */
+	export default {
+		name: "u-form",
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		provide() {
+			return {
+				uForm: this,
+			};
+		},
+		data() {
+			return {
+				formRules: {},
+				// 瑙勫垯鏍¢獙鍣�
+				validator: {},
+				// 鍘熷鐨刴odel蹇収锛岀敤浜巖esetFields鏂规硶閲嶇疆琛ㄥ崟鏃朵娇鐢�
+				originalModel: null,
+			};
+		},
+		watch: {
+			// 鐩戝惉瑙勫垯鐨勫彉鍖�
+			rules: {
+				immediate: true,
+				handler(n) {
+					this.setRules(n);
+				},
+			},
+			// 鐩戝惉灞炴�х殑鍙樺寲锛岄�氱煡瀛愮粍浠秛-form-item閲嶆柊鑾峰彇淇℃伅
+			propsChange(n) {
+				if (this.children?.length) {
+					this.children.map((child) => {
+						// 鍒ゆ柇瀛愮粍浠�(u-form-item)濡傛灉鏈塽pdateParentData鏂规硶鐨勮瘽锛屽氨灏辨墽琛�(鎵ц鐨勭粨鏋滄槸瀛愮粍浠堕噸鏂颁粠鐖剁粍浠舵媺鍙栦簡鏈�鏂扮殑鍊�)
+						typeof child.updateParentData == "function" &&
+							child.updateParentData();
+					});
+				}
+			},
+			// 鐩戝惉model鐨勫垵濮嬪�间綔涓洪噸缃〃鍗曠殑蹇収
+			model: {
+				immediate: true,
+				handler(n) {
+					if (!this.originalModel) {
+						this.originalModel = uni.$u.deepClone(n);
+					}
+				},
+			},
+		},
+		computed: {
+			propsChange() {
+				return [
+					this.errorType,
+					this.borderBottom,
+					this.labelPosition,
+					this.labelWidth,
+					this.labelAlign,
+					this.labelStyle,
+				];
+			},
+		},
+		created() {
+			// 瀛樺偍褰撳墠form涓嬬殑鎵�鏈塽-form-item鐨勫疄渚�
+			// 涓嶈兘瀹氫箟鍦╠ata涓紝鍚﹀垯寰俊灏忕▼搴忎細閫犳垚寰幆寮曠敤鑰屾姤閿�
+			this.children = [];
+		},
+		methods: {
+			// 鎵嬪姩璁剧疆鏍¢獙鐨勮鍒欙紝濡傛灉瑙勫垯涓湁鍑芥暟鐨勮瘽锛屽井淇″皬绋嬪簭涓細杩囨护鎺夛紝鎵�浠ュ彧鑳芥墜鍔ㄨ皟鐢ㄨ缃鍒�
+			setRules(rules) {
+				// 鍒ゆ柇鏄惁鏈夎鍒�
+				if (Object.keys(rules).length === 0) return;
+				if (process.env.NODE_ENV === 'development' && Object.keys(this.model).length === 0) {
+					uni.$u.error('璁剧疆rules锛宮odel蹇呴』璁剧疆锛佸鏋滃凡缁忚缃紝璇峰埛鏂伴〉闈€��');
+					return;
+				};
+				this.formRules = rules;
+				// 閲嶆柊灏嗚鍒欒祴浜圴alidator
+				this.validator = new Schema(rules);
+			},
+			// 娓呯┖鎵�鏈塽-form-item缁勪欢鐨勫唴瀹癸紝鏈川涓婃槸璋冪敤浜唘-form-item缁勪欢涓殑resetField()鏂规硶
+			resetFields() {
+				this.resetModel();
+			},
+			// 閲嶇疆model涓哄垵濮嬪�肩殑蹇収
+			resetModel(obj) {
+				// 鍘嗛亶鎵�鏈塽-form-item锛屾牴鎹叾prop灞炴�э紝杩樺師model鐨勫師濮嬪揩鐓�
+				this.children.map((child) => {
+					const prop = child?.prop;
+					const value = uni.$u.getProperty(this.originalModel, prop);
+					uni.$u.setProperty(this.model, prop, value);
+				});
+			},
+			// 娓呯┖鏍¢獙缁撴灉
+			clearValidate(props) {
+				props = [].concat(props);
+				this.children.map((child) => {
+					// 濡傛灉u-form-item鐨刾rop鍦╬rops鏁扮粍涓紝鍒欐竻闄ゅ搴旂殑鏍¢獙缁撴灉淇℃伅
+					if (props[0] === undefined || props.includes(child.prop)) {
+						child.message = null;
+					}
+				});
+			},
+			// 瀵归儴鍒嗚〃鍗曞瓧娈佃繘琛屾牎楠�
+			async validateField(value, callback, event = null) {
+				// $nextTick鏄繀椤荤殑锛屽惁鍒檓odel鐨勫彉鏇达紝鍙兘浼氬欢鍚庝簬姝ゆ柟娉曠殑鎵ц
+				this.$nextTick(() => {
+					// 鏍¢獙閿欒淇℃伅锛岃繑鍥炵粰鍥炶皟鏂规硶锛岀敤浜庡瓨鏀炬墍鏈塮orm-item鐨勯敊璇俊鎭�
+					const errorsRes = [];
+					// 濡傛灉涓哄瓧绗︿覆锛岃浆涓烘暟缁�
+					value = [].concat(value);
+					// 鍘嗛亶children鎵�鏈夊瓙form-item
+					this.children.map((child) => {
+						// 鐢ㄤ簬瀛樻斁form-item鐨勯敊璇俊鎭�
+						const childErrors = [];
+						if (value.includes(child.prop)) {
+							// 鑾峰彇瀵瑰簲鐨勫睘鎬э紝閫氳繃绫讳技'a.b.c'鐨勫舰寮�
+							const propertyVal = uni.$u.getProperty(
+								this.model,
+								child.prop
+							);
+							// 灞炴�ч摼鏁扮粍
+							const propertyChain = child.prop.split(".");
+							const propertyName =
+								propertyChain[propertyChain.length - 1];
+
+							const rule = this.formRules[child.prop];
+							// 濡傛灉涓嶅瓨鍦ㄥ搴旂殑瑙勫垯锛岀洿鎺ヨ繑鍥烇紝鍚﹀垯鏍¢獙鍣ㄤ細鎶ラ敊
+							if (!rule) return;
+							// rule瑙勫垯鍙负鏁扮粍褰㈠紡锛屼篃鍙负瀵硅薄褰㈠紡锛屾澶勬嫾鎺ユ垚涓烘暟缁�
+							const rules = [].concat(rule);
+
+							// 瀵箁ules鏁扮粍杩涜鏍¢獙
+							for (let i = 0; i < rules.length; i++) {
+								const ruleItem = rules[i];
+								// 灏唘-form-item鐨勮Е鍙戝櫒杞负鏁扮粍褰㈠紡
+								const trigger = [].concat(ruleItem?.trigger);
+								// 濡傛灉鏄湁浼犲叆瑙﹀彂浜嬩欢锛屼絾鏄form-item鍗存病鏈夐厤缃瑙﹀彂鍣ㄧ殑璇濓紝涓嶆墽琛屾牎楠屾搷浣�
+								if (event && !trigger.includes(event)) continue;
+								// 瀹炰緥鍖栨牎楠屽璞★紝浼犲叆鏋勯�犺鍒�
+								const validator = new Schema({
+									[propertyName]: ruleItem,
+								});
+								validator.validate({
+										[propertyName]: propertyVal,
+									},
+									(errors, fields) => {
+										if (uni.$u.test.array(errors)) {
+											errorsRes.push(...errors);
+											childErrors.push(...errors);
+										}
+										child.message =
+											childErrors[0]?.message ?? null;
+									}
+								);
+							}
+						}
+					});
+					// 鎵ц鍥炶皟鍑芥暟
+					typeof callback === "function" && callback(errorsRes);
+				});
+			},
+			// 鏍¢獙鍏ㄩ儴鏁版嵁
+			validate(callback) {
+				// 寮�鍙戠幆澧冩墠鎻愮ず锛岀敓浜х幆澧冧笉浼氭彁绀�
+				if (process.env.NODE_ENV === 'development' && Object.keys(this.formRules).length === 0) {
+					uni.$u.error('鏈缃畆ules锛岃鐪嬫枃妗h鏄庯紒濡傛灉宸茬粡璁剧疆锛岃鍒锋柊椤甸潰銆�');
+					return;
+				}
+				return new Promise((resolve, reject) => {
+					// $nextTick鏄繀椤荤殑锛屽惁鍒檓odel鐨勫彉鏇达紝鍙兘浼氬欢鍚庝簬validate鏂规硶
+					this.$nextTick(() => {
+						// 鑾峰彇鎵�鏈塮orm-item鐨刾rop锛屼氦缁檝alidateField鏂规硶杩涜鏍¢獙
+						const formItemProps = this.children.map(
+							(item) => item.prop
+						);
+						this.validateField(formItemProps, (errors) => {
+							if(errors.length) {
+								// 濡傛灉閿欒鎻愮ず鏂瑰紡涓簍oast锛屽垯杩涜鎻愮ず
+								this.errorType === 'toast' && uni.$u.toast(errors[0].message)
+								reject(errors)
+							} else {
+								resolve(true)
+							}
+						});
+					});
+				});
+			},
+		},
+	};
+</script>
+
+<style lang="scss" scoped>
+</style>

--
Gitblit v1.9.3