¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view class="uni-forms-item" |
| | | :class="['is-direction-' + localLabelPos ,border?'uni-forms-item--border':'' ,border && isFirstBorder?'is-first-border':'']"> |
| | | <slot name="label"> |
| | | <view class="uni-forms-item__label" :class="{'no-label':!label && !isRequired}" |
| | | :style="{width:localLabelWidth,justifyContent: localLabelAlign}"> |
| | | <text v-if="isRequired" class="is-required">*</text> |
| | | <text>{{label}}</text> |
| | | </view> |
| | | </slot> |
| | | <!-- #ifndef APP-NVUE --> |
| | | <view class="uni-forms-item__content"> |
| | | <slot></slot> |
| | | <view class="uni-forms-item__error" :class="{'msg--active':msg}"> |
| | | <text>{{msg}}</text> |
| | | </view> |
| | | </view> |
| | | <!-- #endif --> |
| | | <!-- #ifdef APP-NVUE --> |
| | | <view class="uni-forms-item__nuve-content"> |
| | | <view class="uni-forms-item__content"> |
| | | <slot></slot> |
| | | </view> |
| | | <view class="uni-forms-item__error" :class="{'msg--active':msg}"> |
| | | <text class="error-text">{{msg}}</text> |
| | | </view> |
| | | </view> |
| | | <!-- #endif --> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | /** |
| | | * uni-fomrs-item 表ååç»ä»¶ |
| | | * @description uni-fomrs-item 表ååç»ä»¶ï¼æä¾äºåºç¡å¸å±å·²ç»æ ¡éªè½å |
| | | * @tutorial https://ext.dcloud.net.cn/plugin?id=2773 |
| | | * @property {Boolean} required æ¯å¦å¿
å¡«ï¼å·¦è¾¹æ¾ç¤ºçº¢è²"*"å· |
| | | * @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 } errorMessage æ¾ç¤ºçé误æç¤ºå
容ï¼å¦æä¸ºç©ºå符串æè
falseï¼å䏿¾ç¤ºéè¯¯ä¿¡æ¯ |
| | | * @property {String } name 表ååç屿§åï¼å¨ä½¿ç¨æ ¡éªè§åæ¶å¿
å¡« |
| | | * @property {String } leftIcon ã1.4.0åºå¼ãlabel左边ç徿 ï¼é uni-ui ç徿 åç§° |
| | | * @property {String } iconColor ã1.4.0åºå¼ã左边éè¿iconé
ç½®ç徿 çé¢è²ï¼é»è®¤#606266ï¼ |
| | | * @property {String} validateTrigger = [bind|submit|blur] ã1.4.0åºå¼ãæ ¡éªè§¦å卿¹å¼ é»è®¤ submit |
| | | * @value bind åçååæ¶è§¦å |
| | | * @value submit æäº¤æ¶è§¦å |
| | | * @value blur 失å»ç¦ç¹è§¦å |
| | | * @property {String } labelPosition = [top|left] ã1.4.0åºå¼ãlabelçæåçä½ç½®ï¼é»è®¤leftï¼ |
| | | * @value top 顶鍿¾ç¤º label |
| | | * @value left 左侧æ¾ç¤º label |
| | | */ |
| | | |
| | | export default { |
| | | name: 'uniFormsItem', |
| | | options: { |
| | | virtualHost: true |
| | | }, |
| | | provide() { |
| | | return { |
| | | uniFormItem: this |
| | | } |
| | | }, |
| | | inject: { |
| | | form: { |
| | | from: 'uniForm', |
| | | default: null |
| | | }, |
| | | }, |
| | | props: { |
| | | // è¡¨åæ ¡éªè§å |
| | | rules: { |
| | | type: Array, |
| | | default () { |
| | | return null; |
| | | } |
| | | }, |
| | | // 表ååç屿§åï¼å¨ä½¿ç¨æ ¡éªè§åæ¶å¿
å¡« |
| | | name: { |
| | | type: [String, Array], |
| | | default: '' |
| | | }, |
| | | required: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | label: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // labelç宽度 ï¼é»è®¤ 80 |
| | | labelWidth: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | // label å±
䏿¹å¼ï¼é»è®¤ left åå¼ left/center/right |
| | | labelAlign: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // å¼ºå¶æ¾ç¤ºéè¯¯ä¿¡æ¯ |
| | | errorMessage: { |
| | | type: [String, Boolean], |
| | | default: '' |
| | | }, |
| | | // 1.4.0 å¼ç¨ï¼ç»ä¸ä½¿ç¨ form çæ ¡éªæ¶æº |
| | | // validateTrigger: { |
| | | // type: String, |
| | | // default: '' |
| | | // }, |
| | | // 1.4.0 å¼ç¨ï¼ç»ä¸ä½¿ç¨ form çlabel ä½ç½® |
| | | // labelPosition: { |
| | | // type: String, |
| | | // default: '' |
| | | // }, |
| | | // 1.4.0 以ä¸å±æ§å·²ç»åºå¼ï¼è¯·ä½¿ç¨ #label ææ§½ä»£æ¿ |
| | | leftIcon: String, |
| | | iconColor: { |
| | | type: String, |
| | | default: '#606266' |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | errMsg: '', |
| | | isRequired: false, |
| | | userRules: null, |
| | | localLabelAlign: 'left', |
| | | localLabelWidth: '65px', |
| | | localLabelPos: 'left', |
| | | border: false, |
| | | isFirstBorder: false, |
| | | }; |
| | | }, |
| | | computed: { |
| | | // å¤çéè¯¯ä¿¡æ¯ |
| | | msg() { |
| | | return this.errorMessage || this.errMsg; |
| | | } |
| | | }, |
| | | watch: { |
| | | // è§ååçååéç¥åç»ä»¶æ´æ° |
| | | 'form.formRules'(val) { |
| | | // TODO å¤ç头æ¡vue3 watchä¸çæçé®é¢ |
| | | // #ifndef MP-TOUTIAO |
| | | this.init() |
| | | // #endif |
| | | }, |
| | | 'form.labelWidth'(val) { |
| | | // 宽度 |
| | | this.localLabelWidth = this._labelWidthUnit(val) |
| | | |
| | | }, |
| | | 'form.labelPosition'(val) { |
| | | // æ ç¾ä½ç½® |
| | | this.localLabelPos = this._labelPosition() |
| | | }, |
| | | 'form.labelAlign'(val) { |
| | | |
| | | } |
| | | }, |
| | | created() { |
| | | this.init(true) |
| | | if (this.name && this.form) { |
| | | // TODO å¤ç头æ¡vue3 watchä¸çæçé®é¢ |
| | | // #ifdef MP-TOUTIAO |
| | | this.$watch('form.formRules', () => { |
| | | this.init() |
| | | }) |
| | | // #endif |
| | | |
| | | // çå¬åå |
| | | this.$watch( |
| | | () => { |
| | | const val = this.form._getDataValue(this.name, this.form.localData) |
| | | return val |
| | | }, |
| | | (value, oldVal) => { |
| | | const isEqual = this.form._isEqual(value, oldVal) |
| | | // ç®å夿ååå¼çååï¼åªæåçååæä¼åçæ ¡éª |
| | | // TODO 妿 oldVal = undefined ï¼é£ä¹å¤§æ¦çæ¯æºæ°æ®é没æå¼å¯¼è´ ï¼è¿ä¸ªæ
åµä¸å¦æ ¡éª ,å¯è½ä¸ä¸¥è°¨ ï¼éè¦å¨åè§å¯ |
| | | // fix by mehaotian ææ¶åæ¶ && oldVal !== undefined ï¼å¦æformData ä¸ä¸åå¨ï¼å¯è½ä¼ä¸æ ¡éª |
| | | if (!isEqual) { |
| | | const val = this.itemSetValue(value) |
| | | this.onFieldChange(val, false) |
| | | } |
| | | }, { |
| | | immediate: false |
| | | } |
| | | ); |
| | | } |
| | | |
| | | }, |
| | | // #ifndef VUE3 |
| | | destroyed() { |
| | | if (this.__isUnmounted) return |
| | | this.unInit() |
| | | }, |
| | | // #endif |
| | | // #ifdef VUE3 |
| | | unmounted() { |
| | | this.__isUnmounted = true |
| | | this.unInit() |
| | | }, |
| | | // #endif |
| | | methods: { |
| | | /** |
| | | * å¤é¨è°ç¨æ¹æ³ |
| | | * 设置è§å ï¼ä¸»è¦ç¨äºå°ç¨åºèªå®ä¹æ£éªè§å |
| | | * @param {Array} rules è§åæºæ°æ® |
| | | */ |
| | | setRules(rules = null) { |
| | | this.userRules = rules |
| | | this.init(false) |
| | | }, |
| | | // å
¼å®¹èçæ¬è¡¨åç»ä»¶ |
| | | setValue() { |
| | | // console.log('setValue æ¹æ³å·²ç»å¼ç¨ï¼è¯·ä½¿ç¨ææ°çæ¬ç uni-forms 表åç»ä»¶ä»¥åå
¶ä»å
³èç»ä»¶ã'); |
| | | }, |
| | | /** |
| | | * å¤é¨è°ç¨æ¹æ³ |
| | | * æ ¡éªæ°æ® |
| | | * @param {any} value éè¦æ ¡éªçæ°æ® |
| | | * @param {boolean} æ¯å¦ç«å³æ ¡éª |
| | | * @return {Array|null} æ ¡éªå
容 |
| | | */ |
| | | async onFieldChange(value, formtrigger = true) { |
| | | const { |
| | | formData, |
| | | localData, |
| | | errShowType, |
| | | validateCheck, |
| | | validateTrigger, |
| | | _isRequiredField, |
| | | _realName |
| | | } = this.form |
| | | const name = _realName(this.name) |
| | | if (!value) { |
| | | value = this.form.formData[name] |
| | | } |
| | | // fixd by mehaotian ä¸å¨æ ¡éªåæ¸
空信æ¯ï¼è§£å³éªå±çé®é¢ |
| | | // this.errMsg = ''; |
| | | |
| | | // fix by mehaotian è§£å³æ²¡ææ£éªè§åçæ
åµä¸ï¼æåºé误çé®é¢ |
| | | const ruleLen = this.itemRules.rules && this.itemRules.rules.length |
| | | if (!this.validator || !ruleLen || ruleLen === 0) return; |
| | | |
| | | // æ£éªæ¶æº |
| | | // let trigger = this.isTrigger(this.itemRules.validateTrigger, this.validateTrigger, validateTrigger); |
| | | const isRequiredField = _isRequiredField(this.itemRules.rules || []); |
| | | let result = null; |
| | | // åªæçäº bind æ¶ ï¼æè½å¼å¯æ¶å®æ ¡éª |
| | | if (validateTrigger === 'bind' || formtrigger) { |
| | | // æ ¡éªå½å表å项 |
| | | result = await this.validator.validateUpdate({ |
| | | [name]: value |
| | | }, |
| | | formData |
| | | ); |
| | | |
| | | // 夿æ¯å¦å¿
å¡«,éå¿
å¡«ï¼ä¸å¡«ä¸æ ¡éªï¼å¡«åææ ¡éª ,ææ¶åªå¤ç undefined å空çæ
åµ |
| | | if (!isRequiredField && (value === undefined || value === '')) { |
| | | result = null; |
| | | } |
| | | |
| | | // 夿éè¯¯ä¿¡æ¯æ¾ç¤ºç±»å |
| | | if (result && result.errorMessage) { |
| | | if (errShowType === 'undertext') { |
| | | // è·åéè¯¯ä¿¡æ¯ |
| | | this.errMsg = !result ? '' : result.errorMessage; |
| | | } |
| | | if (errShowType === 'toast') { |
| | | uni.showToast({ |
| | | title: result.errorMessage || 'æ ¡éªé误', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | if (errShowType === 'modal') { |
| | | uni.showModal({ |
| | | title: 'æç¤º', |
| | | content: result.errorMessage || 'æ ¡éªé误' |
| | | }); |
| | | } |
| | | } else { |
| | | this.errMsg = '' |
| | | } |
| | | // éç¥ form ç»ä»¶æ´æ°äºä»¶ |
| | | validateCheck(result ? result : null) |
| | | } else { |
| | | this.errMsg = '' |
| | | } |
| | | return result ? result : null; |
| | | }, |
| | | /** |
| | | * åå§ç»ä»¶æ°æ® |
| | | */ |
| | | init(type = false) { |
| | | const { |
| | | validator, |
| | | formRules, |
| | | childrens, |
| | | formData, |
| | | localData, |
| | | _realName, |
| | | labelWidth, |
| | | _getDataValue, |
| | | _setDataValue |
| | | } = this.form || {} |
| | | // 坹齿¹å¼ |
| | | this.localLabelAlign = this._justifyContent() |
| | | // 宽度 |
| | | this.localLabelWidth = this._labelWidthUnit(labelWidth) |
| | | // æ ç¾ä½ç½® |
| | | this.localLabelPos = this._labelPosition() |
| | | this.isRequired = this.required |
| | | // å°éè¦æ ¡éªçåç»ä»¶å å
¥form éå |
| | | this.form && type && childrens.push(this) |
| | | |
| | | if (!validator || !formRules) return |
| | | // å¤æç¬¬ä¸ä¸ª 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; |
| | | // è·åååççå®åç§° |
| | | const name = _realName(this.name) |
| | | const itemRule = this.userRules || this.rules |
| | | if (typeof formRules === 'object' && itemRule) { |
| | | // åè§åæ¿æ¢ç¶è§å |
| | | formRules[name] = { |
| | | rules: itemRule |
| | | } |
| | | validator.updateSchema(formRules); |
| | | } |
| | | // æ³¨åæ ¡éªè§å |
| | | const itemRules = formRules[name] || {} |
| | | this.itemRules = itemRules |
| | | // æ³¨åæ ¡éªå½æ° |
| | | this.validator = validator |
| | | // é»è®¤å¼èµäº |
| | | this.itemSetValue(_getDataValue(this.name, localData)) |
| | | this.isRequired = this._isRequired() |
| | | |
| | | }, |
| | | unInit() { |
| | | if (this.form) { |
| | | const { |
| | | childrens, |
| | | formData, |
| | | _realName |
| | | } = this.form |
| | | childrens.forEach((item, index) => { |
| | | if (item === this) { |
| | | this.form.childrens.splice(index, 1) |
| | | delete formData[_realName(item.name)] |
| | | } |
| | | }) |
| | | } |
| | | }, |
| | | // 设置item çå¼ |
| | | itemSetValue(value) { |
| | | const name = this.form._realName(this.name) |
| | | const rules = this.itemRules.rules || [] |
| | | const val = this.form._getValue(name, value, rules) |
| | | this.form._setDataValue(name, this.form.formData, val) |
| | | return val |
| | | }, |
| | | |
| | | /** |
| | | * ç§»é¤è¯¥è¡¨åé¡¹çæ ¡éªç»æ |
| | | */ |
| | | clearValidate() { |
| | | this.errMsg = ''; |
| | | }, |
| | | |
| | | // æ¯å¦æ¾ç¤ºæå· |
| | | _isRequired() { |
| | | // TODO 䏿 ¹æ®è§åæ¾ç¤º æå·ï¼èèåç»å
¼å®¹ |
| | | // if (this.form) { |
| | | // if (this.form._isRequiredField(this.itemRules.rules || []) && this.required) { |
| | | // return true |
| | | // } |
| | | // return false |
| | | // } |
| | | return this.required |
| | | }, |
| | | |
| | | // å¤ç坹齿¹å¼ |
| | | _justifyContent() { |
| | | if (this.form) { |
| | | const { |
| | | labelAlign |
| | | } = this.form |
| | | let labelAli = this.labelAlign ? this.labelAlign : labelAlign; |
| | | if (labelAli === 'left') return 'flex-start'; |
| | | if (labelAli === 'center') return 'center'; |
| | | if (labelAli === 'right') return 'flex-end'; |
| | | } |
| | | return 'flex-start'; |
| | | }, |
| | | // å¤ç label宽度åä½ ,ç»§æ¿ç¶å
ç´ çå¼ |
| | | _labelWidthUnit(labelWidth) { |
| | | |
| | | // if (this.form) { |
| | | // const { |
| | | // labelWidth |
| | | // } = this.form |
| | | return this.num2px(this.labelWidth ? this.labelWidth : (labelWidth || (this.label ? 65 : 'auto'))) |
| | | // } |
| | | // return '65px' |
| | | }, |
| | | // å¤ç label ä½ç½® |
| | | _labelPosition() { |
| | | if (this.form) return this.form.labelPosition || 'left' |
| | | return 'left' |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * è§¦åæ¶æº |
| | | * @param {Object} rule å½åè§åå
æ¶æº |
| | | * @param {Object} itemRlue å½åç»ä»¶æ¶æº |
| | | * @param {Object} parentRule ç¶ç»ä»¶æ¶æº |
| | | */ |
| | | isTrigger(rule, itemRlue, parentRule) { |
| | | // bind submit |
| | | if (rule === 'submit' || !rule) { |
| | | if (rule === undefined) { |
| | | if (itemRlue !== 'bind') { |
| | | if (!itemRlue) { |
| | | return parentRule === '' ? 'bind' : 'submit'; |
| | | } |
| | | return 'submit'; |
| | | } |
| | | return 'bind'; |
| | | } |
| | | return 'submit'; |
| | | } |
| | | return 'bind'; |
| | | }, |
| | | num2px(num) { |
| | | if (typeof num === 'number') { |
| | | return `${num}px` |
| | | } |
| | | return num |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .uni-forms-item { |
| | | position: relative; |
| | | display: flex; |
| | | /* #ifdef APP-NVUE */ |
| | | // å¨ nvue ä¸ï¼ä½¿ç¨ margin-bottom error ä¿¡æ¯ä¼è¢«éè |
| | | padding-bottom: 22px; |
| | | /* #endif */ |
| | | /* #ifndef APP-NVUE */ |
| | | margin-bottom: 22px; |
| | | /* #endif */ |
| | | flex-direction: row; |
| | | |
| | | &__label { |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | text-align: left; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | height: 36px; |
| | | padding: 0 12px 0 0; |
| | | /* #ifndef APP-NVUE */ |
| | | vertical-align: middle; |
| | | flex-shrink: 0; |
| | | /* #endif */ |
| | | |
| | | /* #ifndef APP-NVUE */ |
| | | box-sizing: border-box; |
| | | |
| | | /* #endif */ |
| | | &.no-label { |
| | | padding: 0; |
| | | } |
| | | } |
| | | |
| | | &__content { |
| | | /* #ifndef MP-TOUTIAO */ |
| | | // display: flex; |
| | | // align-items: center; |
| | | /* #endif */ |
| | | position: relative; |
| | | font-size: 14px; |
| | | flex: 1; |
| | | /* #ifndef APP-NVUE */ |
| | | box-sizing: border-box; |
| | | /* #endif */ |
| | | flex-direction: row; |
| | | |
| | | /* #ifndef APP || H5 || MP-WEIXIN || APP-NVUE */ |
| | | // TODO å 为å°ç¨åºå¹³å°ä¼å¤ä¸å±æ ç¾èç¹ ï¼æä»¥éè¦å¨å¤ä½èç¹ç»§æ¿å½åæ ·å¼ |
| | | &>uni-easyinput, |
| | | &>uni-data-picker { |
| | | width: 100%; |
| | | } |
| | | |
| | | /* #endif */ |
| | | |
| | | } |
| | | |
| | | & .uni-forms-item__nuve-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | flex: 1; |
| | | } |
| | | |
| | | &__error { |
| | | color: #f56c6c; |
| | | font-size: 12px; |
| | | line-height: 1; |
| | | padding-top: 4px; |
| | | position: absolute; |
| | | /* #ifndef APP-NVUE */ |
| | | top: 100%; |
| | | left: 0; |
| | | transition: transform 0.3s; |
| | | transform: translateY(-100%); |
| | | /* #endif */ |
| | | /* #ifdef APP-NVUE */ |
| | | bottom: 5px; |
| | | /* #endif */ |
| | | |
| | | opacity: 0; |
| | | |
| | | .error-text { |
| | | // åªæ nvue ä¸è¿ä¸ªæ ·å¼æçæ |
| | | color: #f56c6c; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | &.msg--active { |
| | | opacity: 1; |
| | | transform: translateY(0%); |
| | | } |
| | | } |
| | | |
| | | // ä½ç½®ä¿®é¥°æ ·å¼ |
| | | &.is-direction-left { |
| | | flex-direction: row; |
| | | } |
| | | |
| | | &.is-direction-top { |
| | | flex-direction: column; |
| | | |
| | | .uni-forms-item__label { |
| | | padding: 0 0 8px; |
| | | line-height: 1.5715; |
| | | text-align: left; |
| | | /* #ifndef APP-NVUE */ |
| | | white-space: initial; |
| | | /* #endif */ |
| | | } |
| | | } |
| | | |
| | | .is-required { |
| | | // color: $uni-color-error; |
| | | color: #dd524d; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | |
| | | |
| | | .uni-forms-item--border { |
| | | margin-bottom: 0; |
| | | padding: 10px 0; |
| | | // padding-bottom: 0; |
| | | border-top: 1px #eee solid; |
| | | |
| | | /* #ifndef APP-NVUE */ |
| | | .uni-forms-item__content { |
| | | flex-direction: column; |
| | | justify-content: flex-start; |
| | | align-items: flex-start; |
| | | |
| | | .uni-forms-item__error { |
| | | position: relative; |
| | | top: 5px; |
| | | left: 0; |
| | | padding-top: 0; |
| | | } |
| | | } |
| | | |
| | | /* #endif */ |
| | | |
| | | /* #ifdef APP-NVUE */ |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .uni-forms-item__error { |
| | | position: relative; |
| | | top: 0px; |
| | | left: 0; |
| | | padding-top: 0; |
| | | margin-top: 5px; |
| | | } |
| | | |
| | | /* #endif */ |
| | | |
| | | } |
| | | |
| | | .is-first-border { |
| | | /* #ifndef APP-NVUE */ |
| | | border: none; |
| | | /* #endif */ |
| | | /* #ifdef APP-NVUE */ |
| | | border-width: 0; |
| | | /* #endif */ |
| | | } |
| | | </style> |