vue3简易文字验证码

大神勿喷,简易版本,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



<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


<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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1登峰造极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值