From da25434b85fc5b4321c429bf95e719d00ec395bb Mon Sep 17 00:00:00 2001 From: quanyawei <401863037@qq.com> Date: Thu, 11 Jan 2024 16:21:16 +0800 Subject: [PATCH] 定位优化 --- uni_modules/uview-ui/components/u-input/u-input.vue | 354 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 354 insertions(+), 0 deletions(-) diff --git a/uni_modules/uview-ui/components/u-input/u-input.vue b/uni_modules/uview-ui/components/u-input/u-input.vue new file mode 100644 index 0000000..30073eb --- /dev/null +++ b/uni_modules/uview-ui/components/u-input/u-input.vue @@ -0,0 +1,354 @@ +<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> -- Gitblit v1.8.0