¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <view class="u-input" :class="inputClass" :style="[wrapperStyle]"> |
| | | <view class="u-input__content"> |
| | | <view |
| | | class="u-input__content__prefix-icon" |
| | | v-if="prefixIcon || $slots.prefix" |
| | | > |
| | | <slot name="prefix"> |
| | | <u-icon |
| | | :name="prefixIcon" |
| | | size="18" |
| | | :customStyle="prefixIconStyle" |
| | | ></u-icon> |
| | | </slot> |
| | | </view> |
| | | <view class="u-input__content__field-wrapper" @tap="clickHandler"> |
| | | <!-- æ ¹æ®uni-appçinputç»ä»¶ææ¡£ï¼H5åAPPä¸åªè¦å£°æäºpasswordåæ°(æ 论trueè¿æ¯false)ï¼typeå失æï¼æ¤æ¶ |
| | | 为äºé²æ¢type=numberæ¶ï¼ååå¨password屿§ï¼typeæ æï¼æ¤æ¶éè¦è®¾ç½®password为undefined |
| | | --> |
| | | <input |
| | | class="u-input__content__field-wrapper__field" |
| | | :style="[inputStyle]" |
| | | :type="type" |
| | | :focus="focus" |
| | | :cursor="cursor" |
| | | :value="innerValue" |
| | | :auto-blur="autoBlur" |
| | | :disabled="disabled || readonly" |
| | | :maxlength="maxlength" |
| | | :placeholder="placeholder" |
| | | :placeholder-style="placeholderStyle" |
| | | :placeholder-class="placeholderClass" |
| | | :confirm-type="confirmType" |
| | | :confirm-hold="confirmHold" |
| | | :hold-keyboard="holdKeyboard" |
| | | :cursor-spacing="cursorSpacing" |
| | | :adjust-position="adjustPosition" |
| | | :selection-end="selectionEnd" |
| | | :selection-start="selectionStart" |
| | | :password="password || type === 'password' || undefined" |
| | | :ignoreCompositionEvent="ignoreCompositionEvent" |
| | | @input="onInput" |
| | | @blur="onBlur" |
| | | @focus="onFocus" |
| | | @confirm="onConfirm" |
| | | @keyboardheightchange="onkeyboardheightchange" |
| | | /> |
| | | </view> |
| | | <view |
| | | class="u-input__content__clear" |
| | | v-if="isShowClear" |
| | | @tap="onClear" |
| | | > |
| | | <u-icon |
| | | name="close" |
| | | size="11" |
| | | color="#ffffff" |
| | | customStyle="line-height: 12px" |
| | | ></u-icon> |
| | | </view> |
| | | <view |
| | | class="u-input__content__subfix-icon" |
| | | v-if="suffixIcon || $slots.suffix" |
| | | > |
| | | <slot name="suffix"> |
| | | <u-icon |
| | | :name="suffixIcon" |
| | | size="18" |
| | | :customStyle="suffixIconStyle" |
| | | ></u-icon> |
| | | </slot> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import props from "./props.js"; |
| | | /** |
| | | * Input è¾å
¥æ¡ |
| | | * @description æ¤ç»ä»¶ä¸ºä¸ä¸ªè¾å
¥æ¡ï¼é»è®¤æ²¡æè¾¹æ¡åæ ·å¼ï¼æ¯ä¸é¨ä¸ºé
å表åç»ä»¶u-formè设计çï¼å©ç¨å®å¯ä»¥å¿«éå®ç°è¡¨åéªè¯ï¼è¾å
¥å
容ï¼ä¸æéæ©çåè½ã |
| | | * @tutorial https://uviewui.com/components/input.html |
| | | * @property {String | Number} value è¾å
¥çå¼ |
| | | * @property {String} type è¾å
¥æ¡ç±»åï¼è§ä¸æ¹è¯´æ ï¼ é»è®¤ 'text' ï¼ |
| | | * @property {Boolean} fixed 妿 textarea æ¯å¨ä¸ä¸ª position:fixed çåºåï¼éè¦æ¾ç¤ºæå®å±æ§ fixed 为 trueï¼å
¼å®¹æ§ï¼å¾®ä¿¡å°ç¨åºãç¾åº¦å°ç¨åºãåèè·³å¨å°ç¨åºãQQå°ç¨åº ï¼ é»è®¤ false ï¼ |
| | | * @property {Boolean} disabled æ¯å¦ç¦ç¨è¾å
¥æ¡ ï¼ é»è®¤ false ï¼ |
| | | * @property {String} disabledColor ç¦ç¨ç¶ææ¶çèæ¯è²ï¼ é»è®¤ '#f5f7fa' ï¼ |
| | | * @property {Boolean} clearable æ¯å¦æ¾ç¤ºæ¸
餿§ä»¶ ï¼ é»è®¤ false ï¼ |
| | | * @property {Boolean} password æ¯å¦å¯ç ç±»å ï¼ é»è®¤ false ï¼ |
| | | * @property {String | Number} maxlength æå¤§è¾å
¥é¿åº¦ï¼è®¾ç½®ä¸º -1 çæ¶åä¸é嶿大é¿åº¦ ï¼ é»è®¤ -1 ï¼ |
| | | * @property {String} placeholder è¾å
¥æ¡ä¸ºç©ºæ¶çå ä½ç¬¦ |
| | | * @property {String} placeholderClass æå®placeholderçæ ·å¼ç±»ï¼æ³¨æé¡µé¢æç»ä»¶çstyleä¸åäºscopedæ¶ï¼éè¦å¨ç±»ååå/deep/ ï¼ é»è®¤ 'input-placeholder' ï¼ |
| | | * @property {String | Object} placeholderStyle æå®placeholderçæ ·å¼ï¼å符串/对象形å¼ï¼å¦"color: red;" |
| | | * @property {Boolean} showWordLimit æ¯å¦æ¾ç¤ºè¾å
¥åæ°ç»è®¡ï¼åªå¨ type ="text"ætype ="textarea"æ¶ææ ï¼ é»è®¤ false ï¼ |
| | | * @property {String} confirmType 设置å³ä¸è§æé®çæåï¼å
¼å®¹æ§è¯¦è§uni-appææ¡£ ï¼ é»è®¤ 'done' ï¼ |
| | | * @property {Boolean} confirmHold ç¹å»é®çå³ä¸è§æé®æ¶æ¯å¦ä¿æé®ç䏿¶èµ·ï¼H5æ æ ï¼ é»è®¤ false ï¼ |
| | | * @property {Boolean} holdKeyboard focusæ¶ï¼ç¹å»é¡µé¢çæ¶å䏿¶èµ·é®çï¼å¾®ä¿¡å°ç¨åºææ ï¼ é»è®¤ false ï¼ |
| | | * @property {Boolean} focus èªå¨è·åç¦ç¹ï¼å¨ H5 å¹³å°è½å¦èç¦ä»¥å软é®çæ¯å¦è·éå¼¹åºï¼åå³äºå½åæµè§å¨æ¬èº«çå®ç°ãnvue 页é¢ä¸æ¯æï¼é使ç¨ç»ä»¶ç focus()ãblur() æ¹æ³æ§å¶ç¦ç¹ ï¼ é»è®¤ false ï¼ |
| | | * @property {Boolean} autoBlur é®çæ¶èµ·æ¶ï¼æ¯å¦èªå¨å¤±å»ç¦ç¹ï¼ç®åä»
App3.0.0+ææ ï¼ é»è®¤ false ï¼ |
| | | * @property {Boolean} disableDefaultPadding æ¯å¦å»æ iOS ä¸çé»è®¤å
è¾¹è·ï¼ä»
微信å°ç¨åºï¼ä¸type=textareaæ¶ææ ï¼ é»è®¤ false ï¼ |
| | | * @property {String ï½ Number} cursor æå®focusæ¶å
æ çä½ç½®ï¼ é»è®¤ -1 ï¼ |
| | | * @property {String ï½ Number} cursorSpacing è¾å
¥æ¡èç¦æ¶åºé¨ä¸é®ççè·ç¦» ï¼ é»è®¤ 30 ï¼ |
| | | * @property {String ï½ Number} selectionStart å
æ èµ·å§ä½ç½®ï¼èªå¨èéæ¶ææï¼éä¸selection-endæé
ä½¿ç¨ ï¼ é»è®¤ -1 ï¼ |
| | | * @property {String ï½ Number} selectionEnd å
æ ç»æä½ç½®ï¼èªå¨èéæ¶ææï¼éä¸selection-startæé
ä½¿ç¨ ï¼ é»è®¤ -1 ï¼ |
| | | * @property {Boolean} adjustPosition é®ç弹起æ¶ï¼æ¯å¦èªå¨ä¸æ¨é¡µé¢ ï¼ é»è®¤ true ï¼ |
| | | * @property {String} inputAlign è¾å
¥æ¡å
容坹齿¹å¼ï¼ é»è®¤ 'left' ï¼ |
| | | * @property {String | Number} fontSize è¾å
¥æ¡åä½çå¤§å° ï¼ é»è®¤ '15px' ï¼ |
| | | * @property {String} color è¾å
¥æ¡åä½é¢è² ï¼ é»è®¤ '#303133' ï¼ |
| | | * @property {Function} formatter å
容å¼å彿° |
| | | * @property {String} prefixIcon è¾å
¥æ¡åç½®å¾æ |
| | | * @property {String | Object} prefixIconStyle åç½®å¾æ æ ·å¼ï¼å¯¹è±¡æå符串 |
| | | * @property {String} suffixIcon è¾å
¥æ¡åç½®å¾æ |
| | | * @property {String | Object} suffixIconStyle åç½®å¾æ æ ·å¼ï¼å¯¹è±¡æå符串 |
| | | * @property {String} border è¾¹æ¡ç±»åï¼surround-åå¨è¾¹æ¡ï¼bottom-åºé¨è¾¹æ¡ï¼none-æ è¾¹æ¡ ï¼ é»è®¤ 'surround' ï¼ |
| | | * @property {Boolean} readonly æ¯å¦åªè¯»ï¼ä¸disabledä¸åä¹å¤å¨äºdisabledä¼ç½®ç°ç»ä»¶ï¼èreadonlyåä¸ä¼ ï¼ é»è®¤ false ï¼ |
| | | * @property {String} shape è¾å
¥æ¡å½¢ç¶ï¼circle-åå½¢ï¼square-æ¹å½¢ ï¼ é»è®¤ 'square' ï¼ |
| | | * @property {Object} customStyle å®ä¹éè¦ç¨å°çå¤é¨æ ·å¼ |
| | | * @property {Boolean} ignoreCompositionEvent æ¯å¦å¿½ç¥ç»ä»¶å
å¯¹ææ¬åæç³»ç»äºä»¶çå¤çã |
| | | * @example <u-input v-model="value" :password="true" suffix-icon="lock-fill" /> |
| | | */ |
| | | export default { |
| | | name: "u-input", |
| | | mixins: [uni.$u.mpMixin, uni.$u.mixin, props], |
| | | data() { |
| | | return { |
| | | // è¾å
¥æ¡çå¼ |
| | | innerValue: "", |
| | | // æ¯å¦å¤äºè·å¾ç¦ç¹ç¶æ |
| | | focused: false, |
| | | // valueæ¯å¦ç¬¬ä¸æ¬¡ååï¼å¨watchä¸ï¼ç±äºå å
¥immediate屿§ï¼ä¼å¨ç¬¬ä¸æ¬¡è§¦åï¼æ¤æ¶ä¸åºè¯¥è®¤ä¸ºvalueåçäºåå |
| | | firstChange: true, |
| | | // valueç»å®å¼çå忝ç±å
é¨è¿æ¯å¤é¨å¼èµ·ç |
| | | changeFromInner: false, |
| | | // è¿æ»¤å¤çæ¹æ³ |
| | | innerFormatter: value => value |
| | | }; |
| | | }, |
| | | watch: { |
| | | value: { |
| | | immediate: true, |
| | | handler(newVal, oldVal) { |
| | | this.innerValue = newVal; |
| | | /* #ifdef H5 */ |
| | | // å¨H5ä¸ï¼å¤é¨valueåååï¼ä¿®æ¹inputä¸çå¼ï¼ä¸ä¼è§¦å@inputäºä»¶ï¼æ¤æ¶æå¨è°ç¨å¼ååæ¹æ³ |
| | | if ( |
| | | this.firstChange === false && |
| | | this.changeFromInner === false |
| | | ) { |
| | | this.valueChange(); |
| | | } |
| | | /* #endif */ |
| | | this.firstChange = false; |
| | | // éç½®changeFromInnerçå¼ä¸ºfalseï¼æ è¯ä¸ä¸æ¬¡å¼èµ·é»è®¤ä¸ºå¤é¨å¼èµ·ç |
| | | this.changeFromInner = false; |
| | | }, |
| | | }, |
| | | }, |
| | | computed: { |
| | | // æ¯å¦æ¾ç¤ºæ¸
餿§ä»¶ |
| | | isShowClear() { |
| | | const { clearable, readonly, focused, innerValue } = this; |
| | | return !!clearable && !readonly && !!focused && innerValue !== ""; |
| | | }, |
| | | // ç»ä»¶çç±»å |
| | | inputClass() { |
| | | let classes = [], |
| | | { border, disabled, shape } = this; |
| | | border === "surround" && |
| | | (classes = classes.concat(["u-border", "u-input--radius"])); |
| | | classes.push(`u-input--${shape}`); |
| | | border === "bottom" && |
| | | (classes = classes.concat([ |
| | | "u-border-bottom", |
| | | "u-input--no-radius", |
| | | ])); |
| | | return classes.join(" "); |
| | | }, |
| | | // ç»ä»¶çæ ·å¼ |
| | | wrapperStyle() { |
| | | const style = {}; |
| | | // ç¦ç¨ç¶æä¸ï¼è¢«èæ¯è²å ä¸å¯¹åºçæ ·å¼ |
| | | if (this.disabled) { |
| | | style.backgroundColor = this.disabledColor; |
| | | } |
| | | // æ è¾¹æ¡æ¶ï¼å»é¤å
è¾¹è· |
| | | if (this.border === "none") { |
| | | style.padding = "0"; |
| | | } else { |
| | | // ç±äºuni-appçiOSå¼åè
è½åæéï¼å¯¼è´éè¦åå¼åæææ |
| | | style.paddingTop = "6px"; |
| | | style.paddingBottom = "6px"; |
| | | style.paddingLeft = "9px"; |
| | | style.paddingRight = "9px"; |
| | | } |
| | | return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle)); |
| | | }, |
| | | // è¾å
¥æ¡çæ ·å¼ |
| | | inputStyle() { |
| | | const style = { |
| | | color: this.color, |
| | | fontSize: uni.$u.addUnit(this.fontSize), |
| | | textAlign: this.inputAlign |
| | | }; |
| | | return style; |
| | | }, |
| | | }, |
| | | methods: { |
| | | // å¨å¾®ä¿¡å°ç¨åºä¸ï¼ä¸æ¯æå°å½æ°å½åpropsåæ°ï¼æ
åªè½éè¿refå½¢å¼è°ç¨ |
| | | setFormatter(e) { |
| | | this.innerFormatter = e |
| | | }, |
| | | // å½é®çè¾å
¥æ¶ï¼è§¦åinputäºä»¶ |
| | | onInput(e) { |
| | | let { value = "" } = e.detail || {}; |
| | | // æ ¼å¼åè¿æ»¤æ¹æ³ |
| | | const formatter = this.formatter || this.innerFormatter |
| | | const formatValue = formatter(value) |
| | | // 为äºé¿å
propsçååæ°æ®æµç¹æ§ï¼éè¦å
å°innerValueå¼è®¾ç½®ä¸ºå½åå¼ï¼åå¨$nextTickä¸éæ°èµäºè®¾ç½®åçå¼æææ |
| | | this.innerValue = value |
| | | this.$nextTick(() => { |
| | | this.innerValue = formatValue; |
| | | this.valueChange(); |
| | | }) |
| | | }, |
| | | // è¾å
¥æ¡å¤±å»ç¦ç¹æ¶è§¦å |
| | | onBlur(event) { |
| | | this.$emit("blur", event.detail.value); |
| | | // H5端çblurä¼å
äºç¹å»æ¸
餿§ä»¶çç¹å»clickäºä»¶è§¦åï¼å¯¼è´focused |
| | | // ç¬é´ä¸ºfalseï¼ä»èéèäºæ¸
餿§ä»¶èæ æ³è¢«ç¹å»å° |
| | | uni.$u.sleep(50).then(() => { |
| | | this.focused = false; |
| | | }); |
| | | // å°è¯è°ç¨u-formçéªè¯æ¹æ³ |
| | | uni.$u.formValidate(this, "blur"); |
| | | }, |
| | | // è¾å
¥æ¡èç¦æ¶è§¦å |
| | | onFocus(event) { |
| | | this.focused = true; |
| | | this.$emit("focus"); |
| | | }, |
| | | // ç¹å»å®ææé®æ¶è§¦å |
| | | onConfirm(event) { |
| | | this.$emit("confirm", this.innerValue); |
| | | }, |
| | | // é®çé«åº¦åçååçæ¶åè§¦åæ¤äºä»¶ |
| | | // å
¼å®¹æ§ï¼å¾®ä¿¡å°ç¨åº2.7.0+ãApp 3.1.0+ |
| | | onkeyboardheightchange() { |
| | | this.$emit("keyboardheightchange"); |
| | | }, |
| | | // å
容åçååï¼è¿è¡å¤ç |
| | | valueChange() { |
| | | const value = this.innerValue; |
| | | this.$nextTick(() => { |
| | | this.$emit("input", value); |
| | | // æ è¯valueå¼çå忝ç±å
é¨å¼èµ·ç |
| | | this.changeFromInner = true; |
| | | this.$emit("change", value); |
| | | // å°è¯è°ç¨u-formçéªè¯æ¹æ³ |
| | | uni.$u.formValidate(this, "change"); |
| | | }); |
| | | }, |
| | | // ç¹å»æ¸
餿§ä»¶ |
| | | onClear() { |
| | | this.innerValue = ""; |
| | | this.$nextTick(() => { |
| | | this.valueChange(); |
| | | this.$emit("clear"); |
| | | }); |
| | | }, |
| | | /** |
| | | * å¨å®ånvueä¸ï¼äºä»¶æ æ³å泡 |
| | | * å¨æäºæ¶é´ï¼æä»¬å¸æçå¬u-from-itemçç¹å»äºä»¶ï¼æ¤æ¶ä¼å¯¼è´ç¹å»u-form-itemå
çu-inputå |
| | | * æ æ³è§¦åu-form-itemçç¹å»äºä»¶ï¼è¿ééè¿æå¨è°ç¨u-form-itemçæ¹æ³è¿è¡è§¦å |
| | | */ |
| | | clickHandler() { |
| | | // #ifdef APP-NVUE |
| | | if (uni.$u.os() === "android") { |
| | | const formItem = uni.$u.$parent.call(this, "u-form-item"); |
| | | if (formItem) { |
| | | formItem.clickHandler(); |
| | | } |
| | | } |
| | | // #endif |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @import "../../libs/css/components.scss"; |
| | | |
| | | .u-input { |
| | | @include flex(row); |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | flex: 1; |
| | | |
| | | &--radius, |
| | | &--square { |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | &--no-radius { |
| | | border-radius: 0; |
| | | } |
| | | |
| | | &--circle { |
| | | border-radius: 100px; |
| | | } |
| | | |
| | | &__content { |
| | | flex: 1; |
| | | @include flex(row); |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | &__field-wrapper { |
| | | position: relative; |
| | | @include flex(row); |
| | | margin: 0; |
| | | flex: 1; |
| | | |
| | | &__field { |
| | | line-height: 26px; |
| | | text-align: left; |
| | | color: $u-main-color; |
| | | height: 24px; |
| | | font-size: 15px; |
| | | flex: 1; |
| | | } |
| | | } |
| | | |
| | | &__clear { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 100px; |
| | | background-color: #c6c7cb; |
| | | @include flex(row); |
| | | align-items: center; |
| | | justify-content: center; |
| | | transform: scale(0.82); |
| | | margin-left: 4px; |
| | | } |
| | | |
| | | &__subfix-icon { |
| | | margin-left: 4px; |
| | | } |
| | | |
| | | &__prefix-icon { |
| | | margin-right: 4px; |
| | | } |
| | | } |
| | | } |
| | | </style> |