239 lines
4.2 KiB
Vue
239 lines
4.2 KiB
Vue
![]() |
<template>
|
||
|
<view
|
||
|
class="cl-input"
|
||
|
:class="[
|
||
|
{
|
||
|
'is-round': round,
|
||
|
'is-border': border,
|
||
|
'is-disabled': isDisabled,
|
||
|
'is-focus': isFocus,
|
||
|
},
|
||
|
]"
|
||
|
:style="[baseStyle]"
|
||
|
@click="click"
|
||
|
>
|
||
|
<!-- 只读 -->
|
||
|
<view class="cl-input__readonly" v-if="readonly"></view>
|
||
|
|
||
|
<!-- 前 -->
|
||
|
<view class="cl-input__prepend" v-if="$slots.prepend">
|
||
|
<slot name="prepend"></slot>
|
||
|
</view>
|
||
|
|
||
|
<view class="cl-input__wrap">
|
||
|
<input
|
||
|
class="cl-input__inner"
|
||
|
v-model="value"
|
||
|
:type="type"
|
||
|
:password="password"
|
||
|
:placeholder="placeholder"
|
||
|
:disabled="isDisabled"
|
||
|
:focus="focus"
|
||
|
:placeholder-style="placeholderStyle"
|
||
|
:placeholder-class="placeholderClass"
|
||
|
:maxlength="maxlength"
|
||
|
:cursor-spacing="cursorSpacing"
|
||
|
:confirm-type="confirmType"
|
||
|
:confirm-hold="confirmHold"
|
||
|
:adjust-position="adjustPosition"
|
||
|
:holdKeyboard="holdKeyboard"
|
||
|
@input="onInput"
|
||
|
@focus="onFocus"
|
||
|
@blur="onBlur"
|
||
|
@confirm="onConfirm"
|
||
|
@keyboardheightchange="onKeyboardheightchange"
|
||
|
/>
|
||
|
|
||
|
<!-- 清空 -->
|
||
|
<view class="cl-input__clear" v-show="isFocus && clearable" @tap="clear">
|
||
|
<text class="cl-icon-close-border"></text>
|
||
|
</view>
|
||
|
</view>
|
||
|
|
||
|
<!-- 后 -->
|
||
|
<view class="cl-input__append" v-if="$slots.append">
|
||
|
<slot name="append"></slot>
|
||
|
</view>
|
||
|
</view>
|
||
|
</template>
|
||
|
|
||
|
<script lang="ts">
|
||
|
import { computed, defineComponent, ref, watch } from "vue";
|
||
|
import type { PropType } from "vue";
|
||
|
import { useForm, useStyle, useTap } from "../../hooks";
|
||
|
import { keys } from "lodash-es";
|
||
|
|
||
|
export default defineComponent({
|
||
|
name: "cl-input",
|
||
|
|
||
|
props: {
|
||
|
modelValue: {
|
||
|
type: String,
|
||
|
default: "",
|
||
|
},
|
||
|
type: {
|
||
|
type: String as PropType<
|
||
|
"text" | "number" | "idcard" | "digit" | "tel" | "safe-password" | "nickname"
|
||
|
>,
|
||
|
default: "text",
|
||
|
},
|
||
|
password: Boolean,
|
||
|
placeholder: {
|
||
|
type: String,
|
||
|
default: "请填写",
|
||
|
},
|
||
|
clearable: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
placeholderStyle: Object,
|
||
|
placeholderClass: String,
|
||
|
readonly: Boolean,
|
||
|
disabled: Boolean,
|
||
|
round: Boolean,
|
||
|
border: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
focus: Boolean,
|
||
|
maxlength: {
|
||
|
type: [Number, String],
|
||
|
default: 140,
|
||
|
},
|
||
|
cursorSpacing: {
|
||
|
type: Number,
|
||
|
default: 0,
|
||
|
},
|
||
|
confirmType: {
|
||
|
type: String,
|
||
|
default: "done",
|
||
|
},
|
||
|
confirmHold: Boolean,
|
||
|
adjustPosition: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
holdKeyboard: {
|
||
|
type: Boolean,
|
||
|
default: false,
|
||
|
},
|
||
|
},
|
||
|
|
||
|
setup(props, { emit }) {
|
||
|
const { tap } = useTap(emit);
|
||
|
|
||
|
const form = useForm();
|
||
|
|
||
|
// 绑定值
|
||
|
const value = ref("");
|
||
|
|
||
|
watch(
|
||
|
() => props.modelValue,
|
||
|
(val: string) => {
|
||
|
value.value = val;
|
||
|
},
|
||
|
{
|
||
|
immediate: true,
|
||
|
},
|
||
|
);
|
||
|
|
||
|
// 是否聚焦
|
||
|
const isFocus = ref(props.focus);
|
||
|
|
||
|
// 是否禁用
|
||
|
const isDisabled = computed(() => {
|
||
|
return form.disabled.value || props.disabled;
|
||
|
});
|
||
|
|
||
|
// 占位符样式
|
||
|
const placeholderStyle = computed(() => {
|
||
|
const d: any = {
|
||
|
lineHeight: 1,
|
||
|
color: "#a8abb2",
|
||
|
...props.placeholderStyle,
|
||
|
};
|
||
|
|
||
|
return keys(d)
|
||
|
.map((k) => `${k}:${d[k]};`)
|
||
|
.join("");
|
||
|
});
|
||
|
|
||
|
// 输入
|
||
|
function onInput() {
|
||
|
emit("update:modelValue", value.value);
|
||
|
emit("change", value.value);
|
||
|
|
||
|
isFocus.value = Boolean(value.value);
|
||
|
}
|
||
|
|
||
|
// 聚焦
|
||
|
function onFocus(e: any) {
|
||
|
emit("focus", e);
|
||
|
|
||
|
if (value.value) {
|
||
|
isFocus.value = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 失焦
|
||
|
function onBlur(e: any) {
|
||
|
emit("blur", e);
|
||
|
|
||
|
setTimeout(() => {
|
||
|
isFocus.value = false;
|
||
|
}, 0);
|
||
|
}
|
||
|
|
||
|
// 按下确认键
|
||
|
function onConfirm(e: any) {
|
||
|
emit("confirm", e);
|
||
|
search();
|
||
|
}
|
||
|
|
||
|
// 按下搜索键
|
||
|
function search() {
|
||
|
emit("search", value.value);
|
||
|
}
|
||
|
|
||
|
// 清空
|
||
|
function clear() {
|
||
|
value.value = "";
|
||
|
emit("update:modelValue", "");
|
||
|
emit("change", "");
|
||
|
emit("clear");
|
||
|
}
|
||
|
|
||
|
// 键盘高度变化
|
||
|
function onKeyboardheightchange(e: any) {
|
||
|
emit("keyboardheightchange", e);
|
||
|
}
|
||
|
|
||
|
// 点击
|
||
|
function click(e: any) {
|
||
|
if (!isDisabled.value) {
|
||
|
tap(e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
value,
|
||
|
isDisabled,
|
||
|
isFocus,
|
||
|
click,
|
||
|
onInput,
|
||
|
onFocus,
|
||
|
onBlur,
|
||
|
onConfirm,
|
||
|
search,
|
||
|
clear,
|
||
|
onKeyboardheightchange,
|
||
|
placeholderStyle,
|
||
|
...useStyle({
|
||
|
padding: "0 20rpx",
|
||
|
fontSize: 26,
|
||
|
}),
|
||
|
};
|
||
|
},
|
||
|
});
|
||
|
</script>
|