UNPKG

@cqmcui/cqmcui

Version:

轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)

338 lines (337 loc) 9.94 kB
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 };