大神勿喷,简易版本,demo中可以用一下。
需要几个文字自己codelen
赋值 灵活点直接父组件传过去,可以自己改造
首先创建一个生成数字的js
**mathcode.js**
function MathCode(num){
let str = "寻寻觅觅冷冷清清凄凄惨惨戚戚乍暖还寒时候最难将息三杯两盏淡酒怎敌他晚来风急雁过也正伤心却是旧时相识满地黄花堆积憔悴损如今有谁堪摘守着窗儿独自怎生得黑梧桐更兼细雨到黄昏点点滴滴这次第怎一个愁字了得";
let arr = str.split("");
let lastcoe = getArrayItems(arr,num)
return lastcoe;
}
//随机生成指定个数的字符
function getArrayItems(arr, num) {
var temp_array = new Array();
for (var index in arr) {
temp_array.push(arr[index]);
}
var return_array = new Array();
for (var i = 0; i<num; i++) {
if (temp_array.length>0) {
var arrIndex = Math.floor(Math.random()*temp_array.length);
return_array[i] = temp_array[arrIndex];
temp_array.splice(arrIndex, 1);
} else {
break;
}
}
return return_array;
}
export { MathCode }
组件如下TextCode.vue
<!--
* @Author: “1077321622@qq.com” lzr448470520
* @Date: 2023-09-27 14:01:19
* @LastEditors: “1077321622@qq.com” lzr448470520
* @LastEditTime: 2023-10-01 17:31:53
* @FilePath: \viteapp\src\components\TextCode.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="mian">
<el-dialog
v-model="centerDialogVisible"
:title="title"
width="400px"
align-center
:show-close="false"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<div class="img_txt">
<img
src="https://img2.baidu.com/it/u=3913729461,3658245748&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
alt=""
/>
<ul>
<li
v-bind:style="{
top: mathPosition() + 'px',
left: mathPosition() + 'px',
position: 'absolute',
}"
:class="current === index ? 'bgColor' : ''"
v-for="(item, index) in codelist"
:key="index"
@click="handCode(item, index)"
>
{{ item }}
</li>
</ul>
</div>
<template #footer>
<span class="dialog-footer">
{{ showtext }}
<el-button type="primary" @click="Refresh"> 刷新 </el-button>
<el-button type="primary" :disabled="disbtn" @click="handSuccess">
确认
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { MathCode } from "../units/mathcode.js";
import { ElMessage } from "element-plus";
import { ref } from "vue";
let centerDialogVisible = ref(true);
let disbtn = ref(true);
let codelen = ref(4);
let codelist = ref([]);
let title = ref("");
let clickItem = ref([]);
let showtext = ref("");
let current = ref("-1");
let fristtxt = ref("");
let returnBoolen = ref(false);
const emit = defineEmits(["SelechChange"]);
onMounted(() => {
let str = MathCode(codelen.value);
codelist.value = str;
title.value = "请依次点击=>" + str;
fristtxt.value = str.join("");
});
//生成随机坐标
const mathPosition = () => {
return parseInt(Math.random() * (280 - 20) + 20);
};
//刷新验证
const Refresh = () => {
let str = MathCode(codelen.value);
codelist.value = str;
title.value = "请依次点击=>" + str;
clickItem.value = [];
fristtxt.value = str.join("");
showtext.value = "";
returnBoolen.value = false;
current.value = -1;
};
const handCode = (item, index) => {
current.value = index;
if (clickItem.value.length < codelen.value) {
clickItem.value.push(item);
showtext.value = clickItem.value.join("");
if (clickItem.value.join("") == fristtxt.value) {
disbtn.value = false;
returnBoolen.value = true;
} else {
disbtn.value = true;
returnBoolen.value = false;
if (clickItem.value.length == codelen.value) {
ElMessage.error("验证码有误,请刷新重试");
}
}
}
};
const handSuccess = () => {
if (returnBoolen.value) {
centerDialogVisible.value = false;
emit("SelechChange", returnBoolen.value);
}
};
</script>
<style scoped>
.dialog-footer button:first-child {
margin-right: 10px;
}
.img_txt {
width: 100%;
height: 350px;
background: #f4f4f4;
cursor: pointer;
position: relative;
}
.img_txt img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.img_txt ul {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.img_txt ul li {
font-size: 30px;
font-weight: bold;
color: #fff;
position: relative;
}
.bgColor {
background-color: red;
border-radius: 50%;
padding: 5px;
}
</style>
使用方式在页面中引入
import TextCode from "./TextCode.vue";
例如 login.vue
<!--
* @Author: your name
* @Date: 2022-03-04 17:33:01
* @LastEditTime: 2023-10-01 17:33:58
* @LastEditors: “1077321622@qq.com” lzr448470520
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \viteapp\src\components\Login.vue
-->
<template>
<div class="logo">
<div class="logo_center">
<div class="logo_pic">
<p class="p1"><img src="" alt="" /></p>
<p class="p2">vue3( setup 语法糖)开发听歌系统</p>
</div>
<div class="logo_input">
<el-input
v-model="username"
type="password"
class="username"
placeholder="请输入163邮箱账号"
>
<template #suffix>
<el-icon class="el-input__icon"><Stamp /></el-icon>
</template>
</el-input>
<el-input
v-model="password"
type="password"
class="pass"
placeholder="请输入密码"
>
</el-input>
<div class="btn">
<button class="btn" @click="gologin">登录</button>
<!-- <el-button type="success" style="width: 100%; height: 100%" plain @click="gologin">
登录</el-button
> -->
</div>
</div>
</div>
<TextCode @SelechChange="SelechChange"></TextCode>
</div>
</template>
<script setup>
import { Login,Login1 } from "../api/index.js";
import { ElMessage } from "element-plus";
import TextCode from "./TextCode.vue";
//l路由引入
import { useStore } from "vuex";
import Cookies from "js-cookie";
const username = ref("11111@163.com");
const password = ref("222222");
const router = useRouter();
const store = useStore();
let status = ref(false);
const SelechChange = (val)=>{
// 赋值
status.value = val;
};
//登录
const gologin = () => {
if(status.value){
//alert("写自己的逻辑")
}else{
ElMessage.error("请刷新页面点击正确验证码")
}
};
</script>
<style lang="scss" scoped>
.logo {
width: 100%;
height: 100%;
// background: url("../assets/login/logobj.png");
background: firebrick;
background-size: 100% 100%;
background-repeat: no-repeat;
position: relative;
.logo_center {
width: 395px;
height: 435px;
background: #fff;
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
border-radius: 8px;
.logo_pic {
width: 100%;
height: 170px;
position: relative;
.p1 {
width: 120px;
height: 95px;
background: url("../assets/login/logopic.png");
position: absolute;
top: 25px;
left: 0px;
right: 0px;
bottom: 0px;
margin: auto;
background-size: 100% 100%;
background-repeat: no-repeat;
position: relative;
}
.p2 {
width: 100%;
height: 20px;
text-align: center;
position: absolute;
top: 140px;
left: 0px;
right: 0px;
bottom: 0px;
margin: auto;
color: #606266;
font-size: 15px;
}
}
.logo_input {
width: 70%;
margin: 20px auto 0px auto;
.pass {
margin-top: 20px;
}
button {
width: 100%;
margin-top: 10px;
--glow-color: rgb(217, 176, 255);
--glow-spread-color: rgba(191, 123, 255, 0.781);
--enhanced-glow-color: rgb(231, 206, 255);
--btn-color: rgb(100, 61, 136);
border: 0.25em solid var(--glow-color);
padding: 1em 3em;
color: var(--glow-color);
font-size: 15px;
font-weight: bold;
background-color: var(--btn-color);
border-radius: 1em;
outline: none;
box-shadow: 0 0 1em 0.25em var(--glow-color),
0 0 4em 1em var(--glow-spread-color),
inset 0 0 0.75em 0.25em var(--glow-color);
text-shadow: 0 0 0.5em var(--glow-color);
position: relative;
transition: all 0.3s;
}
button::after {
pointer-events: none;
content: "";
position: absolute;
top: 120%;
left: 0;
height: 100%;
width: 100%;
background-color: var(--glow-spread-color);
filter: blur(2em);
opacity: 0.7;
transform: perspective(1.5em) rotateX(35deg) scale(1, 0.6);
}
button:hover {
color: var(--btn-color);
background-color: var(--glow-color);
box-shadow: 0 0 1em 0.25em var(--glow-color),
0 0 4em 2em var(--glow-spread-color),
inset 0 0 0.75em 0.25em var(--glow-color);
}
button:active {
box-shadow: 0 0 0.6em 0.25em var(--glow-color),
0 0 2.5em 2em var(--glow-spread-color),
inset 0 0 0.5em 0.25em var(--glow-color);
}
.btn:hover::before {
transform: translateX(0);
}
}
}
}
</style>