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