vue3.0實現炫酷的隨機驗證碼功能


先上圖

接下來樓一眼實現代碼

這里說明一下,我用到了vue3.0,vant3.0以及阿里圖標,vant 很人性化針對vue3.0新出了個vant3.0版本,阿里則是適配vue3.0的。我們將verify驗證碼進行了封裝,內部用進行了hook以及工具的封裝。

登錄頁代碼 login.vue

<template>
  <div class="login">
    <span class="iconfont icongouwuche"></span>
    <van-form @submit="onSubmit">
      <van-field
        v-model="username"
        name="username"
        label="用戶名"
        placeholder="用戶名"
        :rules="[{ required: true, message: '請填寫用戶名' }]"
      />
      <van-field
        v-model="password"
        type="password"
        name="password"
        label="密碼"
        placeholder="密碼"
        :rules="[{ required: true, message: '請填寫密碼' }]"
      />
      <van-field
        center
        clearable
        label="驗證碼"
        placeholder="輸入驗證碼"
        v-model="verify"
      >
      </van-field>
      <ImgVerify ref="verifyRef" />
      <div style="margin: 16px">
        <van-button round block color="#1baeae" native-type="submit">
          登錄</van-button
        >
      </div>
    </van-form>
  </div>
</template>

<script>
import { reactive, ref, toRefs } from "vue";
import ImgVerify from "@/components/ImgVerify";
export default {
  components: { ImgVerify },
  setup(props, con) {
    const verifyRef = ref(null);

    const state = reactive({
      username: "",
      password: "",
      verify: "",
    });
    const onSubmit = (values) => {
      if (state.verify.toLowerCase() == verifyRef.value.imgCode.toLowerCase()) {
        //   提交時判斷是否是正確驗證碼
        alert("輸入正確");
        TODO;
        //
      }
    };

    return {
      ...toRefs(state),
      onSubmit,
      verifyRef,
    };
  },
};
</script>

<style lang='scss' scoped>
.login {
  /* background: #eee; */
}
div {
  font-size: 14px;
  .icongouwuche {
    padding-top: 40px;
    font-size: 120px;
  }
}
</style>

驗證碼組件 ImgVerify.vue

這里只是簡單地獲取以及排版,正正的邏輯放到了hook中

<template>
  <div>
    <canvas
      ref="verify"
      :width="width"
      :height="height"
      @click="handleDraw"
    ></canvas>
  </div>
</template>

<script>
import {ref } from "vue";
import {setVerify} from '../hooks/Verify'
export default {
  setup(props, con) {
    const verify = ref(null);
    return{
        ...setVerify(verify)
    }
  },
};
</script>

<style lang='scss' scoped>
</style>

我們先看一下封裝好的tool工具函數。

Tool.js

//隨機數
export function randomNum(min, max) {
    return parseInt(Math.random() * (max - min + 1) + min);
};
//隨機顏色
export function randomColor(min, max) {
    const r = randomNum(min, max);
    const g = randomNum(min, max);
    const b = randomNum(min, max);
    return `rgb(${r},${g},${b})`;
};

接下來重頭戲實現驗證碼

verify.js

import { onMounted, toRefs, reactive } from "vue";
import { randomColor, randomNum } from '../utils/Tools'
export function setVerify(verify) {
    const state = reactive({
        pool: "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",   // 隨機字符串
        width: 120,                                     //展示區域寬度
        height: 40,                                     //展示區域高度
        imgCode: "",                                    //保存頁面的內容(用來判斷輸入驗證是否滿足改code)
    });
    // 1、初始展示
    onMounted(() => {
        draw();
        state.imgCode = draw();
    });
    // 2、點擊圖片重新繪制
    const handleDraw = () => {
        draw();
        state.imgCode = draw();
    };

    // 3、繪制隨機內容
    const draw = () => {
        /*
         *   一、填充顏色
         * 1、生成畫布
         * 2、填充顏色與位置
         * 3、填充位置
         */
        const ctx = verify.value.getContext("2d");
        ctx.fillStyle = randomColor(180, 230);
        ctx.fillRect(0, 0, state.width, state.height);

        /*
         *    二、生成4個隨機數
         *  1、七扭八歪
         *  2、隨機大小
         * 3、畫吧柳梢,各種色兒
         */
        let imgCode = "";
        for (let i = 0; i < 4; i++) {
            const text = state.pool[randomNum(0, state.pool.length - 1)];

            const fontSize = randomNum(18, 40);
            const deg = randomNum(-30, 30);
            /*
             *  繪制文字並讓四個文字在不同的位置顯示的思路 :
             * 1、定義字體
             * 2、定義對齊方式
             * 3、填充不同的顏色
             * 4、保存當前的狀態(以防止以上的狀態受影響)
             * 5、平移translate()
             * 6、旋轉 rotate()
             * 7、填充文字
             * 8、restore出棧
             * */
            ctx.font = fontSize + "px Simhei";
            ctx.textBaseline = "top";
            ctx.fillStyle = randomColor(80, 150);

ctx.save(); ctx.translate(30 * i + 15, 15); ctx.rotate((deg * Math.PI) / 180); ctx.fillText(text, -15 + 5, -15); ctx.restore(); imgCode += text; } /* * 三、隨機產生5條干擾線,干擾線的顏色要淺一點 */ for (let i = 0; i < 5; i++) { ctx.beginPath(); ctx.moveTo(randomNum(0, state.width), randomNum(0, state.height)); ctx.lineTo(randomNum(0, state.width), randomNum(0, state.height)); ctx.strokeStyle = randomColor(180, 230); ctx.closePath(); ctx.stroke(); } /* * 四、隨機產生40個干擾的小點 */ for (let i = 0; i < 40; i++) { ctx.beginPath(); ctx.arc( randomNum(0, state.width), randomNum(0, state.height), 1, 0, 2 * Math.PI ); ctx.closePath(); ctx.fillStyle = randomColor(150, 200); ctx.fill(); } return imgCode; }; return { ...toRefs(state), handleDraw, verify, }; }

一個vscode快熟生成vue3代碼片段的方法

1、選擇      文件---》首選項---》代碼片段---》

2、新建json

 

3、配置json

 "Print to console": {
        "prefix": "vue3",
        "body": [
            "<template>",
            "<div>",
            "",
            "</div>",
            "</template>",
            "",
            "<script>",
            "export default {",
            "   components: {},",
         
            "   setup(props,con){}",
            "}",
            "</script>",
            "",
            "<style lang='scss' scoped>",
            "",
            "</style>",
            "$2"
        ],
        "description": "Vue3模板"
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM