birdpaper-ui
Version:
一个通用的 vue3 UI组件库。A common vue3 UI component library.
101 lines (100 loc) • 3.23 kB
JavaScript
"use strict";
const dom = require("../../utils/dom.js");
const vue = require("vue");
const _sfc_main = vue.defineComponent({
name: "VerifyCode",
props: {
/** 绑定值 Binding value */
modelValue: { type: String, default: "" },
/** 输入框尺寸 Size of the input */
size: { type: String, default: "normal" },
/** 验证码长度 Verify code length */
length: { type: Number, default: 6 },
/** 是否禁用 Disabled or not */
disabled: { type: Boolean, default: false },
/** 是否只读状态 Readonly or not */
readonly: { type: Boolean, default: false },
/** 是否警示状态 Danger or not */
isDanger: { type: Boolean, default: false },
/** 是否匿文模式 */
isPassword: { type: Boolean, default: false }
},
emits: ["update:modelValue", "finish"],
setup(props, { emit }) {
const name = "bp-verifycode";
let inpRefs = [];
const setItemRef = (el) => {
inpRefs.push(el);
};
const globalValue = vue.ref([]);
const onInput = (e, index) => {
if (props.disabled || props.readonly)
return;
const targetValue = e.target.value.replace(/\s+/g, "");
!!targetValue && index + 1 < props.length && inpRefs[index + 1].focus();
updateValue();
};
const onPaste = (e) => {
if (props.disabled || props.readonly)
return;
var clipboardData = e.clipboardData || window["clipboardData"];
var pastedData = clipboardData.getData("Text");
globalValue.value = [...pastedData].slice(0, props.length);
};
const onFocus = () => {
if (props.disabled || props.readonly)
return;
const len = globalValue.value.length;
return inpRefs[len >= props.length ? len - 1 : len].focus();
};
const onKeydown = (e) => {
if (props.disabled || props.readonly)
return;
const index = dom.getChildrenIndex(e.target);
const val = globalValue.value[index];
const isLastEl = index === props.length - 1;
switch (e.key) {
case "Backspace":
globalValue.value.splice(isLastEl && val ? index : index - 1, 1);
onFocus();
updateValue();
break;
}
};
const updateValue = () => {
if (props.disabled || props.readonly)
return;
emit("update:modelValue", globalValue.value.join("").substring(0, props.length));
if (globalValue.value.length === props.length) {
emit("finish");
}
};
const inpType = vue.computed(() => props.isPassword ? "password" : "text");
const inpClass = vue.computed(() => {
const status = getStatus();
return [name, `${name}-size-${props.size}`, `${name}-status-${status}`];
});
function getStatus() {
return props.disabled && "disabled" || props.readonly && "readonly" || props.isDanger && "danger" || "normal";
}
vue.watch(
() => props.modelValue,
() => {
globalValue.value = props.modelValue.split("") || [];
},
{ immediate: true }
);
return {
name,
setItemRef,
inpType,
inpClass,
globalValue,
onFocus,
onInput,
onPaste,
onKeydown
};
}
});
module.exports = _sfc_main;