<template>
<view
class="u-input"
:class="{
'u-input--border': border,
}"
@tap.stop="inputClick"
>
<textarea
v-if="type == 'textarea'"
:class="{ 'error-input-110': validateState, input110: !validateState }"
class="u-input__input u-input__textarea"
:value="value"
:placeholder="placeholder"
:disabled="disabled"
:maxlength="inputMaxlength"
:fixed="fixed"
:focus="focused"
:autoHeight="autoHeight"
@input="handleInput"
@blur="handleBlur"
@focus="onFocus"
@confirm="onConfirm"
/>
<input
v-else
:class="{ 'error-input-110': validateState, input110: !validateState }"
class="u-input__input"
:type="type == 'password' ? 'text' : type"
:value="defaultValue"
:password="type == 'password' && !showPassword"
:placeholder="placeholder"
:disabled="disabled || type === 'select'"
:maxlength="inputMaxlength"
:focus="focused"
:confirmType="confirmType"
:cursor-spacing="getCursorSpacing"
:confirm-hold="confirmHold"
@focus="onFocus"
@blur="handleBlur"
@input="handleInput"
@confirm="onConfirm"
/>
<view class="u-input__right-icon u-flex">
<view
class="u-input__right-icon__clear u-input__right-icon__item"
v-if="clearable && value != '' && focused && !imgRightSrc"
>
<image src="/static/base-module/icons/close.png" class="icon-close" @touchstart="onClear"></image>
</view>
<image
v-if="imgRightSrc"
class="u-input__right-img"
:src="imgRightSrc"
@longtap="handerImg"
></image>
<view
class="u-input__right-icon__clear u-input__right-icon__item"
v-if="passwordIcon && type == 'password'"
>
<image
src="/static/base-module/icons/hidepwd.png"
class="icon"
mode="aspectFit"
v-if="!showPassword"
@click="showPassword = !showPassword"
></image>
<image
src="/static/base-module/icons/showpwd.png"
class="icon"
mode="aspectFit"
v-if="showPassword"
@click="showPassword = !showPassword"
></image>
</view>
<view
class="u-input__right-icon--select u-input__right-icon__item"
v-if="type == 'select'"
>
<u-icon
name="arrow-down"
size="14"
color="#000"
:class="{
'u-input__right-icon--select--reverse': selectOpen,
}"
></u-icon>
</view>
</view>
</view>
</template>
<script>
import Emitter from "../../libs/util/emitter.js";
export default {
name: "u-input",
mixins: [Emitter],
props: {
value: {
type: [String, Number],
default: "",
},
confirmHold:{
type: Boolean,
default: true,
},
type: {
type: String,
default: "text",
},
inputAlign: {
type: String,
default: "left",
},
placeholder: {
type: String,
default: "请输入内容",
},
disabled: {
type: Boolean,
default: false,
},
maxlength: {
type: [Number, String],
default: 140,
},
placeholderStyle: {
type: String,
default: "color:rgba(140,140,140,1)",
},
confirmType: {
type: String,
default: "done",
},
customStyle: {
type: Object,
default() {
return {};
},
},
fixed: {
type: Boolean,
default: false,
},
focus: {
type: Boolean,
default: false,
},
passwordIcon: {
type: Boolean,
default: true,
},
border: {
type: Boolean,
default: false,
},
borderColor: {
type: String,
default: "#dcdfe6",
},
autoHeight: {
type: Boolean,
default: false,
},
selectOpen: {
type: Boolean,
default: false,
},
height: {
type: [Number, String],
default: 110 / 3.64,
},
clearable: {
type: Boolean,
default: true,
},
cursorSpacing: {
type: [Number, String],
default: 0,
},
imgRightSrc: {
type: String,
default: "",
},
},
data() {
return {
defaultValue: this.value,
inputHeight: 70,
textareaHeight: 100,
validateState: false,
focused: false,
showPassword: false,
marginRight: 0,
};
},
watch: {
value(nVal, oVal) {
this.defaultValue = nVal;
if (nVal != oVal && this.type == "select")
this.handleInput({
detail: {
value: nVal,
},
});
if (oVal == "" && this.inputAlign == "right") this.getMarginRight();
},
focused(nVal) {
if (this.clearable && this.value) {
this.getMarginRight();
}
},
},
computed: {
inputMaxlength() {
return Number(this.maxlength);
},
getStyle() {
let style = {};
style.minHeight = this.height
? this.height + "rpx"
: this.type == "textarea"
? this.textareaHeight + "rpx"
: this.inputHeight + "rpx";
style.marginRight = this.marginRight + "px";
style = Object.assign(style, this.customStyle);
return style;
},
getCursorSpacing() {
return Number(this.cursorSpacing);
},
},
created() {
this.$on("on-form-item-error", this.onFormItemError);
},
mounted() {
this.getMarginRight();
},
methods: {
getMarginRight() {
this.$nextTick(() => {
this.$uGetRect(".u-input__right-icon").then((res) => {
this.marginRight = res.width;
});
});
},
handleInput(event) {
this.defaultValue = event.detail.value;
this.$emit("input", event.detail.value);
this.$nextTick(() => {
this.dispatch("u-form-item", "on-form-change", event.detail.value);
});
},
handleBlur(event) {
setTimeout(() => {
this.focused = false;
}, 50)
this.$emit("blur", event.detail.value);
this.$nextTick(() => {
this.dispatch("u-form-item", "on-form-blur", event.detail.value);
});
},
onFormItemError(status) {
console.log(status)
this.validateState = status;
},
onFocus(event) {
this.focused = true
this.$emit("focus");
},
onConfirm(e) {
this.$emit("confirm", e.detail.value);
},
onClear(event) {
this.$emit("input", "");
},
inputClick() {
this.$emit("click");
},
handerImg() {
this.$emit("handerRightImg");
},
},
};
</script>
<style lang="scss" scoped>
.u-input {
position: relative;
flex: 1;
&__input {
font-size: rpx(40);
color:rgba(0,0,0,1);
width: 100%;
height: rpx(110);
}
/deep/ .u-icon {
transition: transform 0.4s;
}
/deep/ .u-icon__icon {
font-weight: bold !important;
}
/deep/ .u-input__right-img {
width: 19.78rpx;
height: 19.78rpx;
margin-top: 50%;
border-left: 1px solid #bebebe;
padding-left: 7.41rpx;
}
&__textarea {
width: auto;
font-size: rpx(40);
color:rgba(0,0,0,1);
min-height: rpx(142);
}
&--border {
border-radius: 6rpx;
border-radius: 4px;
background: rgba(255, 255, 255, 1);
border-radius: 3.88rpx;
border: 1px solid rgba(135, 135, 135, 1);
box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 1),
inset 0px 2px 5px 0px rgba(0, 0, 0, 0.2);
}
&--error {
border-color: $u-type-error !important;
}
&__right-icon {
position: absolute;
right: rpx(34);
top: 50%;
margin-top: rpx(-22);
z-index: 3;
&__item {
margin-left: 5rpx;
}
&--select {
transition: transform 0.4s;
&--reverse {
transform: rotate(-180deg);
}
}
}
}
.u-input__input {
padding: 0 rpx(20);
}
.icon-close {
width: rpx(44);
height: rpx(44);
}
.icon {
width: rpx(64);
height: rpx(64);
}
</style>