automated_uniapp/uni_modules/cool-ui/components/cl-input/cl-input.vue

239 lines
4.2 KiB
Vue
Raw Normal View History

2025-01-09 16:16:11 +08:00
<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>