From fe75cffbf3bae6777aa2794fd89fa5dc37f5df8d Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期二, 15 七月 2025 10:11:23 +0800 Subject: [PATCH] 项目初始化 --- src/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue | 679 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 679 insertions(+), 0 deletions(-) diff --git a/src/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue b/src/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue new file mode 100644 index 0000000..a779cec --- /dev/null +++ b/src/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue @@ -0,0 +1,679 @@ +<template> + <view + class="uni-easyinput" + :class="{ 'uni-easyinput-error': msg }" + :style="boxStyle" + > + <view + class="uni-easyinput__content" + :class="inputContentClass" + :style="inputContentStyle" + > + <slot name="prefixIcon"> + <uni-icons + v-if="prefixIcon" + class="content-clear-icon" + :type="prefixIcon" + color="#c0c4cc" + @click="onClickIcon('prefix')" + size="22" + ></uni-icons> + </slot> + <textarea + v-if="type === 'textarea'" + class="uni-easyinput__content-textarea" + :class="{ 'input-padding': inputBorder }" + :name="name" + :value="val" + :placeholder="placeholder" + :placeholderStyle="placeholderStyle" + :disabled="disabled" + placeholder-class="uni-easyinput__placeholder-class" + :maxlength="inputMaxlength" + :focus="focused" + :autoHeight="autoHeight" + @input="onInput" + @blur="_Blur" + @focus="_Focus" + @confirm="onConfirm" + ></textarea> + <input + v-else + :type="type === 'password' ? 'text' : type" + class="uni-easyinput__content-input" + :style="inputStyle" + :name="name" + :value="val" + :password="!showPassword && type === 'password'" + :placeholder="placeholder" + :placeholderStyle="placeholderStyle" + placeholder-class="uni-easyinput__placeholder-class" + :disabled="disabled" + :maxlength="inputMaxlength" + :focus="focused" + :confirmType="confirmType" + @focus="_Focus" + @blur="_Blur" + @input="onInput" + @confirm="onConfirm" + /> + <template v-if="type === 'password' && passwordIcon"> + <!-- 寮�鍚瘑鐮佹椂鏄剧ず灏忕溂鐫� --> + <uni-icons + v-if="isVal" + class="content-clear-icon" + :class="{ 'is-textarea-icon': type === 'textarea' }" + :type="showPassword ? 'eye-slash-filled' : 'eye-filled'" + :size="22" + :color="focusShow ? primaryColor : '#c0c4cc'" + @click="onEyes" + > + </uni-icons> + </template> + <template v-else-if="suffixIcon || $slots.suffixIcon"> + <slot name="suffixIcon"> + <uni-icons + v-if="suffixIcon" + class="content-clear-icon" + :type="suffixIcon" + color="#c0c4cc" + @click="onClickIcon('suffix')" + size="22" + ></uni-icons> + </slot> + </template> + <template v-else> + <uni-icons + v-if="clearable && isVal && !disabled && type !== 'textarea'" + class="content-clear-icon" + :class="{ 'is-textarea-icon': type === 'textarea' }" + type="clear" + :size="clearSize" + :color="msg ? '#dd524d' : focusShow ? primaryColor : '#c0c4cc'" + @click="onClear" + ></uni-icons> + </template> + <slot name="right"></slot> + </view> + </view> +</template> + +<script> +/** + * Easyinput 杈撳叆妗� + * @description 姝ょ粍浠跺彲浠ュ疄鐜拌〃鍗曠殑杈撳叆涓庢牎楠岋紝鍖呮嫭 "text" 鍜� "textarea" 绫诲瀷銆� + * @tutorial https://ext.dcloud.net.cn/plugin?id=3455 + * @property {String} value 杈撳叆鍐呭 + * @property {String } type 杈撳叆妗嗙殑绫诲瀷锛堥粯璁ext锛� password/text/textarea/.. + * @value text 鏂囨湰杈撳叆閿洏 + * @value textarea 澶氳鏂囨湰杈撳叆閿洏 + * @value password 瀵嗙爜杈撳叆閿洏 + * @value number 鏁板瓧杈撳叆閿洏锛屾敞鎰廼OS涓奱pp-vue寮瑰嚭鐨勬暟瀛楅敭鐩樺苟闈�9瀹牸鏂瑰紡 + * @value idcard 韬唤璇佽緭鍏ラ敭鐩橈紝淇°�佹敮浠樺疂銆佺櫨搴︺�丵Q灏忕▼搴� + * @value digit 甯﹀皬鏁扮偣鐨勬暟瀛楅敭鐩� 锛孉pp鐨刵vue椤甸潰銆佸井淇°�佹敮浠樺疂銆佺櫨搴︺�佸ご鏉°�丵Q灏忕▼搴忔敮鎸� + * @property {Boolean} clearable 鏄惁鏄剧ず鍙充晶娓呯┖鍐呭鐨勫浘鏍囨帶浠讹紝鐐瑰嚮鍙竻绌鸿緭鍏ユ鍐呭锛堥粯璁rue锛� + * @property {Boolean} autoHeight 鏄惁鑷姩澧為珮杈撳叆鍖哄煙锛宼ype涓簍extarea鏃舵湁鏁堬紙榛樿true锛� + * @property {String } placeholder 杈撳叆妗嗙殑鎻愮ず鏂囧瓧 + * @property {String } placeholderStyle placeholder鐨勬牱寮�(鍐呰仈鏍峰紡锛屽瓧绗︿覆)锛屽"color: #ddd" + * @property {Boolean} focus 鏄惁鑷姩鑾峰緱鐒︾偣锛堥粯璁alse锛� + * @property {Boolean} disabled 鏄惁绂佺敤锛堥粯璁alse锛� + * @property {Number } maxlength 鏈�澶ц緭鍏ラ暱搴︼紝璁剧疆涓� -1 鐨勬椂鍊欎笉闄愬埗鏈�澶ч暱搴︼紙榛樿140锛� + * @property {String } confirmType 璁剧疆閿洏鍙充笅瑙掓寜閽殑鏂囧瓧锛屼粎鍦╰ype="text"鏃剁敓鏁堬紙榛樿done锛� + * @property {Number } clearSize 娓呴櫎鍥炬爣鐨勫ぇ灏忥紝鍗曚綅px锛堥粯璁�15锛� + * @property {String} prefixIcon 杈撳叆妗嗗ご閮ㄥ浘鏍� + * @property {String} suffixIcon 杈撳叆妗嗗熬閮ㄥ浘鏍� + * @property {String} primaryColor 璁剧疆涓婚鑹诧紙榛樿#2979ff锛� + * @property {Boolean} trim 鏄惁鑷姩鍘婚櫎涓ょ鐨勭┖鏍� + * @value both 鍘婚櫎涓ょ绌烘牸 + * @value left 鍘婚櫎宸︿晶绌烘牸 + * @value right 鍘婚櫎鍙充晶绌烘牸 + * @value start 鍘婚櫎宸︿晶绌烘牸 + * @value end 鍘婚櫎鍙充晶绌烘牸 + * @value all 鍘婚櫎鍏ㄩ儴绌烘牸 + * @value none 涓嶅幓闄ょ┖鏍� + * @property {Boolean} inputBorder 鏄惁鏄剧ずinput杈撳叆妗嗙殑杈规锛堥粯璁rue锛� + * @property {Boolean} passwordIcon type=password鏃舵槸鍚︽樉绀哄皬鐪肩潧鍥炬爣 + * @property {Object} styles 鑷畾涔夐鑹� + * @event {Function} input 杈撳叆妗嗗唴瀹瑰彂鐢熷彉鍖栨椂瑙﹀彂 + * @event {Function} focus 杈撳叆妗嗚幏寰楃劍鐐规椂瑙﹀彂 + * @event {Function} blur 杈撳叆妗嗗け鍘荤劍鐐规椂瑙﹀彂 + * @event {Function} confirm 鐐瑰嚮瀹屾垚鎸夐挳鏃惰Е鍙� + * @event {Function} iconClick 鐐瑰嚮鍥炬爣鏃惰Е鍙� + * @slot prefixIcon 杈撳叆妗嗗ご閮ㄦ彃妲� + * @slot suffixIcon 杈撳叆妗嗗熬閮ㄦ彃妲� + * @example <uni-easyinput v-model="mobile"></uni-easyinput> + */ +function obj2strClass(obj) { + let classess = ""; + for (let key in obj) { + const val = obj[key]; + if (val) { + classess += `${key} `; + } + } + return classess; +} + +function obj2strStyle(obj) { + let style = ""; + for (let key in obj) { + const val = obj[key]; + style += `${key}:${val};`; + } + return style; +} +export default { + name: "uni-easyinput", + emits: [ + "click", + "iconClick", + "update:modelValue", + "input", + "focus", + "blur", + "confirm", + "clear", + "eyes", + "change", + ], + model: { + prop: "modelValue", + event: "update:modelValue", + }, + options: { + virtualHost: true, + }, + inject: { + form: { + from: "uniForm", + default: null, + }, + formItem: { + from: "uniFormItem", + default: null, + }, + }, + props: { + name: String, + value: [Number, String], + modelValue: [Number, String], + type: { + type: String, + default: "text", + }, + clearable: { + type: Boolean, + default: true, + }, + autoHeight: { + type: Boolean, + default: false, + }, + placeholder: { + type: String, + default: " ", + }, + placeholderStyle: String, + focus: { + type: Boolean, + default: false, + }, + disabled: { + type: Boolean, + default: false, + }, + maxlength: { + type: [Number, String], + default: 140, + }, + confirmType: { + type: String, + default: "done", + }, + clearSize: { + type: [Number, String], + default: 24, + }, + inputBorder: { + type: Boolean, + default: true, + }, + prefixIcon: { + type: String, + default: "", + }, + suffixIcon: { + type: String, + default: "", + }, + trim: { + type: [Boolean, String], + default: true, + }, + passwordIcon: { + type: Boolean, + default: true, + }, + primaryColor: { + type: String, + default: "#2979ff", + }, + styles: { + type: Object, + default() { + return { + color: "#333", + disableColor: "#F7F6F6", + borderColor: "#e5e5e5", + }; + }, + }, + errorMessage: { + type: [String, Boolean], + default: "", + }, + }, + data() { + return { + focused: false, + val: "", + showMsg: "", + border: false, + isFirstBorder: false, + showClearIcon: false, + showPassword: false, + focusShow: false, + localMsg: "", + }; + }, + computed: { + // 杈撳叆妗嗗唴鏄惁鏈夊�� + isVal() { + const val = this.val; + // fixed by mehaotian 澶勭悊鍊间负0鐨勬儏鍐碉紝瀛楃涓�0涓嶅湪澶勭悊鑼冨洿 + if (val || val === 0) { + return true; + } + return false; + }, + + msg() { + // console.log('computed', this.form, this.formItem); + // if (this.form) { + // return this.errorMessage || this.formItem.errMsg; + // } + // TODO 澶勭悊澶存潯 formItem 涓� errMsg 涓嶆洿鏂扮殑闂 + return this.localMsg || this.errorMessage; + }, + // 鍥犱负uniapp鐨刬nput缁勪欢鐨刴axlength缁勪欢蹇呴』瑕佹暟鍊硷紝杩欓噷杞负鏁板�硷紝鐢ㄦ埛鍙互浼犲叆瀛楃涓叉暟鍊� + inputMaxlength() { + return Number(this.maxlength); + }, + + // 澶勭悊澶栧眰鏍峰紡鐨剆tyle + boxStyle() { + return `color:${ + this.inputBorder && this.msg ? "#e43d33" : this.styles.color + };`; + }, + // input 鍐呭鐨勭被鍜屾牱寮忓鐞� + inputContentClass() { + return obj2strClass({ + "is-input-border": this.inputBorder, + "is-input-error-border": this.inputBorder && this.msg, + "is-textarea": this.type === "textarea", + "is-disabled": this.disabled, + }); + }, + inputContentStyle() { + const focusColor = this.focusShow + ? this.primaryColor + : this.styles.borderColor; + const borderColor = this.inputBorder && this.msg ? "#dd524d" : focusColor; + return obj2strStyle({ + "border-color": borderColor || "#e5e5e5", + "background-color": this.disabled + ? this.styles.disableColor + : this.styles.backgroundColor, + }); + }, + // input鍙充晶鏍峰紡 + inputStyle() { + const paddingRight = + this.type === "password" || this.clearable || this.prefixIcon + ? "" + : "10px"; + return obj2strStyle({ + "padding-right": paddingRight, + "padding-left": this.prefixIcon ? "" : "10px", + }); + }, + }, + watch: { + value(newVal) { + this.val = newVal; + }, + modelValue(newVal) { + this.val = newVal; + }, + focus(newVal) { + this.$nextTick(() => { + this.focused = this.focus; + this.focusShow = this.focus; + }); + }, + }, + created() { + this.init(); + // TODO 澶勭悊澶存潯vue3 computed 涓嶇洃鍚� inject 鏇存敼鐨勯棶棰橈紙formItem.errMsg锛� + if (this.form && this.formItem) { + this.$watch("formItem.errMsg", (newVal) => { + this.localMsg = newVal; + }); + } + }, + mounted() { + this.$nextTick(() => { + this.focused = this.focus; + this.focusShow = this.focus; + }); + }, + methods: { + /** + * 鍒濆鍖栧彉閲忓�� + */ + init() { + if (this.value || this.value === 0) { + this.val = this.value; + } else if (this.modelValue || this.modelValue === 0) { + this.val = this.modelValue; + } else { + this.val = null; + } + }, + + /** + * 鐐瑰嚮鍥炬爣鏃惰Е鍙� + * @param {Object} type + */ + onClickIcon(type) { + this.$emit("iconClick", type); + }, + + /** + * 鏄剧ず闅愯棌鍐呭锛屽瘑鐮佹鏃剁敓鏁� + */ + onEyes() { + this.showPassword = !this.showPassword; + this.$emit("eyes", this.showPassword); + }, + + /** + * 杈撳叆鏃惰Е鍙� + * @param {Object} event + */ + onInput(event) { + let value = event.detail.value; + // 鍒ゆ柇鏄惁鍘婚櫎绌烘牸 + if (this.trim) { + if (typeof this.trim === "boolean" && this.trim) { + value = this.trimStr(value); + } + if (typeof this.trim === "string") { + value = this.trimStr(value, this.trim); + } + } + if (this.errMsg) this.errMsg = ""; + this.val = value; + // TODO 鍏煎 vue2 + this.$emit("input", value); + // TODO銆�鍏煎銆�vue3 + this.$emit("update:modelValue", value); + }, + + /** + * 澶栭儴璋冪敤鏂规硶 + * 鑾峰彇鐒︾偣鏃惰Е鍙� + * @param {Object} event + */ + onFocus() { + this.$nextTick(() => { + this.focused = true; + }); + this.$emit("focus", null); + }, + + _Focus(event) { + this.focusShow = true; + this.$emit("focus", event); + }, + + /** + * 澶栭儴璋冪敤鏂规硶 + * 澶卞幓鐒︾偣鏃惰Е鍙� + * @param {Object} event + */ + onBlur() { + this.focused = false; + this.$emit("focus", null); + }, + _Blur(event) { + let value = event.detail.value; + this.focusShow = false; + this.$emit("blur", event); + // 鏍规嵁绫诲瀷杩斿洖鍊硷紝鍦╡vent涓幏鍙栫殑鍊肩悊璁轰笂璁查兘鏄痵tring + this.$emit("change", this.val); + // 澶卞幓鐒︾偣鏃跺弬涓庤〃鍗曟牎楠� + if (this.form && this.formItem) { + const { validateTrigger } = this.form; + if (validateTrigger === "blur") { + this.formItem.onFieldChange(); + } + } + }, + + /** + * 鎸変笅閿洏鐨勫彂閫侀敭 + * @param {Object} e + */ + onConfirm(e) { + this.$emit("confirm", this.val); + this.$emit("change", this.val); + }, + + /** + * 娓呯悊鍐呭 + * @param {Object} event + */ + onClear(event) { + this.val = ""; + // TODO 鍏煎 vue2 + this.$emit("input", ""); + // TODO 鍏煎 vue2 + // TODO銆�鍏煎銆�vue3 + this.$emit("update:modelValue", ""); + // 鐐瑰嚮鍙夊彿瑙﹀彂 + this.$emit("clear"); + }, + + /** + * 鍘婚櫎绌烘牸 + */ + trimStr(str, pos = "both") { + if (pos === "both") { + return str.trim(); + } else if (pos === "left") { + return str.trimLeft(); + } else if (pos === "right") { + return str.trimRight(); + } else if (pos === "start") { + return str.trimStart(); + } else if (pos === "end") { + return str.trimEnd(); + } else if (pos === "all") { + return str.replace(/\s+/g, ""); + } else if (pos === "none") { + return str; + } + return str; + }, + }, +}; +</script> + +<style lang="scss"> +$uni-error: #e43d33; +$uni-border-1: #dcdfe6 !default; + +.uni-easyinput { + /* #ifndef APP-NVUE */ + width: 100%; + /* #endif */ + flex: 1; + position: relative; + text-align: left; + color: #333; + font-size: 14px; +} + +.uni-easyinput__content { + flex: 1; + /* #ifndef APP-NVUE */ + width: 100%; + display: flex; + box-sizing: border-box; + // min-height: 36px; + /* #endif */ + flex-direction: row; + align-items: center; + // 澶勭悊border鍔ㄧ敾鍒氬紑濮嬫樉绀洪粦鑹茬殑闂 + border-color: #fff; + transition-property: border-color; + transition-duration: 0.3s; +} + +.uni-easyinput__content-input { + /* #ifndef APP-NVUE */ + width: auto; + /* #endif */ + position: relative; + overflow: hidden; + flex: 1; + line-height: 1; + font-size: 14px; + height: 35px; + // min-height: 36px; +} + +.uni-easyinput__placeholder-class { + color: #999; + font-size: 12px; + // font-weight: 200; +} + +.is-textarea { + align-items: flex-start; +} + +.is-textarea-icon { + margin-top: 5px; +} + +.uni-easyinput__content-textarea { + position: relative; + overflow: hidden; + flex: 1; + line-height: 1.5; + font-size: 14px; + margin: 6px; + margin-left: 0; + height: 80px; + min-height: 80px; + /* #ifndef APP-NVUE */ + min-height: 80px; + width: auto; + /* #endif */ +} + +.input-padding { + padding-left: 10px; +} + +.content-clear-icon { + padding: 0 5px; +} + +.label-icon { + margin-right: 5px; + margin-top: -1px; +} + +// 鏄剧ず杈规 +.is-input-border { + /* #ifndef APP-NVUE */ + display: flex; + box-sizing: border-box; + /* #endif */ + flex-direction: row; + align-items: center; + border: 1px solid $uni-border-1; + border-radius: 4px; + /* #ifdef MP-ALIPAY */ + overflow: hidden; + /* #endif */ +} + +.uni-error-message { + position: absolute; + bottom: -17px; + left: 0; + line-height: 12px; + color: $uni-error; + font-size: 12px; + text-align: left; +} + +.uni-error-msg--boeder { + position: relative; + bottom: 0; + line-height: 22px; +} + +.is-input-error-border { + border-color: $uni-error; + + .uni-easyinput__placeholder-class { + color: mix(#fff, $uni-error, 50%); + } +} + +.uni-easyinput--border { + margin-bottom: 0; + padding: 10px 15px; + // padding-bottom: 0; + border-top: 1px #eee solid; +} + +.uni-easyinput-error { + padding-bottom: 0; +} + +.is-first-border { + /* #ifndef APP-NVUE */ + border: none; + /* #endif */ + /* #ifdef APP-NVUE */ + border-width: 0; + /* #endif */ +} + +.is-disabled { + background-color: #f7f6f6; + color: #d5d5d5; + + .uni-easyinput__placeholder-class { + color: #d5d5d5; + font-size: 12px; + } +} +</style> -- Gitblit v1.9.3