@cqmcui/cqmcui
Version:
轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)
338 lines (337 loc) • 9.94 kB
JavaScript
import { ref, reactive, computed, watch, onMounted, h, resolveComponent, openBlock, createElementBlock, normalizeClass, createElementVNode, renderSlot, createBlock, resolveDynamicComponent, normalizeStyle, toDisplayString, createTextVNode, createCommentVNode, withDirectives, createVNode, mergeProps, vShow } from "vue";
import { c as createComponent } from "./component-81a4c1d0.js";
import { MaskClose } from "@cqmcui/icons-vue";
import { _ as _export_sfc } from "./_plugin-vue_export-helper-cc2b3d55.js";
import "../locale/lang";
function trimExtraChar(value, char, regExp) {
const index2 = value.indexOf(char);
if (index2 === -1) {
return value;
}
if (char === "-" && index2 !== 0) {
return value.slice(0, index2);
}
return value.slice(0, index2 + 1) + value.slice(index2).replace(regExp, "");
}
function formatNumber(value, allowDot = true, allowMinus = true) {
if (allowDot) {
value = trimExtraChar(value, ".", /\./g);
} else {
value = value.split(".")[0];
}
if (allowMinus) {
value = trimExtraChar(value, "-", /-/g);
} else {
value = value.replace(/-/, "");
}
const regExp = allowDot ? /[^-0-9.]/g : /[^-0-9]/g;
return value.replace(regExp, "");
}
const { componentName, create } = createComponent("input");
const _sfc_main = create({
props: {
type: {
type: String,
default: "text"
},
modelValue: {
type: String,
default: ""
},
placeholder: {
type: String,
default: ""
},
inputAlign: {
type: String,
default: "left"
},
required: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
readonly: {
type: Boolean,
default: false
},
maxLength: {
type: [String, Number],
default: ""
},
clearable: {
type: Boolean,
default: false
},
clearSize: {
type: [String, Number],
default: "14"
},
border: {
type: Boolean,
default: true
},
formatTrigger: {
type: String,
default: "onChange"
},
formatter: {
type: Function,
default: null
},
showWordLimit: {
type: Boolean,
default: false
},
autofocus: {
type: Boolean,
default: false
},
confirmType: {
type: String,
default: "done"
},
error: {
type: Boolean,
default: false
},
showClearIcon: {
type: Boolean,
default: false
}
},
components: { MaskClose },
emits: ["update:modelValue", "blur", "focus", "clear", "keypress", "click", "click-input"],
setup(props, { emit, slots }) {
const active = ref(false);
const inputRef = ref();
const getModelValue = () => String(props.modelValue ?? "");
const renderInput = (type) => {
return h("input", {
style: styles,
...inputType(type)
});
};
const state = reactive({
focused: false,
validateFailed: false,
// 校验失败
validateMessage: ""
// 校验信息
});
const classes = computed(() => {
const prefixCls = componentName;
return {
[prefixCls]: true,
[`${prefixCls}--disabled`]: props.disabled,
[`${prefixCls}--required`]: props.required,
[`${prefixCls}--error`]: props.error,
[`${prefixCls}--border`]: props.border
};
});
const styles = computed(() => {
return {
textAlign: props.inputAlign
};
});
const inputType = (type) => {
if (type === "number") {
return {
type: "text"
};
}
if (type === "digit") {
return {
type: "tel"
};
}
return { type };
};
const onInput = (event) => {
if (!event.target.composing) {
const input = event.target;
let value = input.value;
if (props.maxLength && value.length > Number(props.maxLength)) {
value = value.slice(0, Number(props.maxLength));
}
updateValue(value);
}
};
const updateValue = (value, trigger = "onChange") => {
var _a;
if (props.type === "digit") {
value = formatNumber(value, false, false);
}
if (props.type === "number") {
value = formatNumber(value, true, true);
}
if (props.formatter && trigger === props.formatTrigger) {
value = props.formatter(value);
}
if (((_a = inputRef == null ? void 0 : inputRef.value) == null ? void 0 : _a.value) !== value) {
inputRef.value.value = value;
}
if (value !== props.modelValue) {
emit("update:modelValue", value);
}
};
const onFocus = (event) => {
if (props.disabled || props.readonly) {
return;
}
const input = event.target;
input.value;
active.value = true;
emit("focus", event);
};
const onBlur = (event) => {
if (props.disabled || props.readonly) {
return;
}
setTimeout(() => {
active.value = false;
}, 200);
const input = event.target;
let value = input.value;
if (props.maxLength && value.length > Number(props.maxLength)) {
value = value.slice(0, Number(props.maxLength));
}
updateValue(getModelValue(), "onBlur");
emit("blur", event);
};
const clear = (event) => {
event.stopPropagation();
if (props.disabled)
return;
emit("update:modelValue", "", event);
emit("clear", "", event);
};
const resetValidation = () => {
if (state.validateFailed) {
state.validateFailed = false;
state.validateMessage = "";
}
};
const onClickInput = (event) => {
if (props.disabled) {
return;
}
emit("click-input", event);
};
const onClick = (event) => {
emit("click", event);
};
const startComposing = ({ target }) => {
target.composing = true;
};
const endComposing = ({ target }) => {
if (target.composing) {
target.composing = false;
target.dispatchEvent(new Event("input"));
}
};
watch(
() => props.modelValue,
() => {
updateValue(getModelValue());
resetValidation();
}
);
onMounted(() => {
updateValue(getModelValue(), props.formatTrigger);
});
return {
renderInput,
inputRef,
active,
classes,
styles,
inputType,
onInput,
onFocus,
onBlur,
clear,
startComposing,
endComposing,
onClick,
onClickInput
};
}
});
const _hoisted_1 = { class: "cqmc-input-value" };
const _hoisted_2 = { class: "cqmc-input-inner" };
const _hoisted_3 = { class: "cqmc-input-left-box" };
const _hoisted_4 = { class: "cqmc-input-box" };
const _hoisted_5 = {
key: 0,
class: "cqmc-input-word-limit"
};
const _hoisted_6 = { class: "cqmc-input-word-num" };
const _hoisted_7 = {
key: 0,
class: "cqmc-input-clear-box"
};
const _hoisted_8 = { class: "cqmc-input-right-box" };
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_MaskClose = resolveComponent("MaskClose");
return openBlock(), createElementBlock("view", {
class: normalizeClass(_ctx.classes),
onClick: _cache[0] || (_cache[0] = (...args) => _ctx.onClick && _ctx.onClick(...args))
}, [
createElementVNode("view", _hoisted_1, [
createElementVNode("view", _hoisted_2, [
createElementVNode("view", _hoisted_3, [
renderSlot(_ctx.$slots, "left")
]),
createElementVNode("view", _hoisted_4, [
(openBlock(), createBlock(resolveDynamicComponent(_ctx.renderInput(_ctx.type)), {
class: "input-text",
ref: "inputRef",
style: normalizeStyle(_ctx.styles),
maxlength: _ctx.maxLength,
placeholder: _ctx.placeholder,
disabled: _ctx.disabled,
readonly: _ctx.readonly,
value: _ctx.modelValue,
formatTrigger: _ctx.formatTrigger,
autofocus: _ctx.autofocus,
enterkeyhint: _ctx.confirmType,
onInput: _ctx.onInput,
onFocus: _ctx.onFocus,
onBlur: _ctx.onBlur,
onClick: _ctx.onClickInput,
onChange: _ctx.endComposing,
onCompositionend: _ctx.endComposing,
onCompositionstart: _ctx.startComposing
}, null, 40, ["style", "maxlength", "placeholder", "disabled", "readonly", "value", "formatTrigger", "autofocus", "enterkeyhint", "onInput", "onFocus", "onBlur", "onClick", "onChange", "onCompositionend", "onCompositionstart"])),
_ctx.showWordLimit && _ctx.maxLength ? (openBlock(), createElementBlock("view", _hoisted_5, [
createElementVNode("span", _hoisted_6, toDisplayString(_ctx.modelValue ? _ctx.modelValue.length : 0), 1),
createTextVNode("/" + toDisplayString(_ctx.maxLength), 1)
])) : createCommentVNode("", true)
]),
_ctx.clearable && !_ctx.readonly ? withDirectives((openBlock(), createElementBlock("view", _hoisted_7, [
renderSlot(_ctx.$slots, "clear", {}, () => [
createVNode(_component_MaskClose, mergeProps({ class: "cqmc-input-clear" }, _ctx.$attrs, {
size: _ctx.clearSize,
width: _ctx.clearSize,
height: _ctx.clearSize,
onClick: _ctx.clear
}), null, 16, ["size", "width", "height", "onClick"])
])
], 512)), [
[vShow, (_ctx.active || _ctx.showClearIcon) && _ctx.modelValue.length > 0]
]) : createCommentVNode("", true),
createElementVNode("view", _hoisted_8, [
renderSlot(_ctx.$slots, "right")
])
])
])
], 2);
}
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
index as default
};