验证码组件
<template>
<div class="code-style" @click="changeCode">
<canvas id="canvas" width="150" height="35"></canvas>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive, toRefs } from "vue";
export default defineComponent({
name: "name",
props: {
postCode: {
type: Function,
required: true,
},
},
components: {},
setup(props) {
const data = reactive({
code: "",
darkColor: [
`rgb(75, 0, 130)`,
`rgb(0, 0, 139)`,
`rgb(0, 100, 0)`,
`rgb(255, 140, 0)`,
],
changeCode() {
data.initCode();
},
getUnknow() {
const codeArr = [];
for (let index = 0; index < 5; index++) {
codeArr.push({
id: index,
// 取随机字母,最后一位是数字
code:
index === 4
? "ABCDEFGHIJKLMNOPQRSTUVWSYZ"[
parseInt((Math.random() * 25).toFixed(0))
]
: parseInt((Math.random() * 9).toFixed(0)),
// 取y轴偏移----偏移角度在18-33中间,跟字体大小有关
rotateNum: parseInt((18 + Math.random() * 15).toFixed(0)),
});
}
data.code = codeArr.map((item) => item.code).join("");
props.postCode(data.code);
return codeArr;
},
initCode() {
// 获取页面canvas
const canvas = document.getElementById("canvas");
// 获得渲染上下文和它的绘画功能。getContext()只有一个参数,上下文的格式。
const ctx = (canvas as any).getContext("2d");
// 创建img标签
const img = new Image();
// 图片准备就绪执行
img.onload = () => {
ctx.drawImage(img, 0, 0);
ctx.font = "22px songti";
ctx.fillStyle =
data.darkColor[parseInt((Math.random() * 3).toFixed(0))];
ctx.textAlign = "left";
const codeArr = data.getUnknow();
codeArr.map((code, index) => {
ctx.fillText(code.code, 20 * (index + 1), code.rotateNum);
});
};
img.src = require("@/assets/codebgc.jpg");
},
});
onMounted(() => {
data.initCode();
});
return { ...toRefs(data) };
},
});
</script>
<style lang="scss">
.code-style:hover {
cursor: pointer;
}
</style>
父组件调用
<Captcha ref="captcha" :postCode="getCode" />
getCode用于获取子组件中的验证码值用于比较,当你需要更换验证码的时候(比如请求失败的时候),就需要调用子组件中方法,参考Vue3.0 + ts 父组件如何获取(调用)子组件的数据(方法)