vue3+vite3+typescript實(shí)現(xiàn)驗(yàn)證碼功能及表單驗(yàn)證效果
驗(yàn)證碼組件
<template>
<div class="captcha" style="display: flex;">
<canvas ref="canvas" width="100" height="40"></canvas>
</div>
<div class="valicode-btn">
<el-button type="text" @click="refresh">看不清,換一張</el-button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
const emits = defineEmits(['getCode'])
const canvasRef = ref<HTMLCanvasElement | null>(null)
const ctx = ref<CanvasRenderingContext2D | null>(null)
const code = ref('')
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
const charLength = chars.length
function getRandomChar() {
return chars.charAt(Math.floor(Math.random() * charLength))
}
function draw() {
if (!ctx.value) return
ctx.value.clearRect(0, 0, canvasRef.value!.width, canvasRef.value!.height)
let x = 10
for (let i = 0; i < 4; i++) {
const c = getRandomChar()
code.value += c
ctx.value.font = 'bold 20px Arial'
ctx.value.fillStyle = '#333'
ctx.value.fillText(c, x, 25)
x += 20
}
for (let i = 0; i < 10; i++) {
ctx.value.strokeStyle = '#ccc'
ctx.value.beginPath()
ctx.value.moveTo(Math.random() * 100, Math.random() * 40)
ctx.value.lineTo(Math.random() * 100, Math.random() * 40)
ctx.value.stroke()
}
emits('getCode', code.value)
}
function refresh() {
code.value = ''
draw()
emits('getCode', code.value)
}
onMounted(() => {
const code = ref('')
canvasRef.value = document.querySelector('canvas')
emits('getCode', code.value)
ctx.value = canvasRef.value?.getContext('2d')
draw()
})
</script>
<style scoped>
.captcha {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.valicode-btn{
height:50px;
line-height: 50px;
}
</style>
?? 這是一個(gè)Vue組件,包含一個(gè)驗(yàn)證碼的canvas和一個(gè)刷新按鈕。具體解釋如下:
<template>標(biāo)簽中包含了組件的模板,其中包含了一個(gè)class為captcha的div,其中包含了一個(gè)canvas元素和一個(gè)class為valicode-btn的div,后者包含了一個(gè)刷新按鈕。<script>標(biāo)簽中使用了Vue 3的Composition API,包含了以下內(nèi)容:import語句引入了Vue 3的ref和onMounted函數(shù),以及defineEmits函數(shù)用于定義組件的自定義事件。const關(guān)鍵字定義了一個(gè)canvasRef變量,用于引用canvas元素;一個(gè)ctx變量,用于引用canvas的2D上下文;一個(gè)code變量,用于存儲驗(yàn)證碼;一個(gè)chars變量,用于存儲可用于生成驗(yàn)證碼的字符;一個(gè)charLength變量,用于存儲可用于生成驗(yàn)證碼的字符的數(shù)量。getRandomChar函數(shù)用于從chars中隨機(jī)獲取一個(gè)字符??。draw函數(shù)用于繪制驗(yàn)證碼。首先清空canvas,然后循環(huán)4次,每次從chars中隨機(jī)獲取一個(gè)字符,并將其繪制到canvas上。同時(shí),將字符添加到code變量中。接著循環(huán)10次,每次繪制一條隨機(jī)的直線,用于增加驗(yàn)證碼的復(fù)雜度。refresh函數(shù)用于刷新驗(yàn)證碼。首先清空code變量,然后調(diào)用draw函數(shù)重新繪制驗(yàn)證碼,并觸發(fā)自定義事件getCode,將新的驗(yàn)證碼傳遞給父組件。onMounted函數(shù)用于在組件掛載后執(zhí)行一些操作。首先定義一個(gè)code變量,然后引用canvas元素和2D上下文,并調(diào)用draw函數(shù)繪制驗(yàn)證碼。最后觸發(fā)自定義事件getCode,將驗(yàn)證碼傳遞給父組件。
3.<style>標(biāo)簽中定義了組件的樣式,其中.captcha類用于設(shè)置驗(yàn)證碼和刷新按鈕的布局,.valicode-btn類用于設(shè)置刷新按鈕的樣式。scoped屬性用于將樣式限定在組件內(nèi)部。
父組件
<div class="validate-code">
<div style="display: flex">
<el-form-item label="驗(yàn)證碼:" prop="valicode">
<el-input v-model="form.valicode"/>
</el-form-item>
<valicode ref="refresh" @getCode="getCode" width="150px" />
</div>
</div>
<script setup lang="ts">
const code = ref('')
const getCode=(value:any)=> {
code.value = value
console.log(value);
}
</script>驗(yàn)證碼組件是通過引入一個(gè)名為valicode的組件來實(shí)現(xiàn)的。當(dāng)驗(yàn)證碼組件生成新的驗(yàn)證碼時(shí),會通過@getCode事件將驗(yàn)證碼傳遞給父組件,并通過console.log打印出來。父組件通過v-model綁定了驗(yàn)證碼輸入框的值,當(dāng)用戶輸入驗(yàn)證碼時(shí),會將輸入的值保存在form.valicode中。整個(gè)表單的驗(yàn)證依賴于prop屬性,即valicode。如果用戶未輸入驗(yàn)證碼或輸入的驗(yàn)證碼與生成的驗(yàn)證碼不匹配,則表單驗(yàn)證不通過。
表單驗(yàn)證
const rules=reactive<FormRules>({
valicode: [
{ required: true, message: '請輸入驗(yàn)證碼', trigger: 'blur' },
{ validator: checkCode, trigger: 'blur' },
],
})
const checkCode=(rule: any, value: any, callback: any)=>{
console.log(code.value);
if (!value) {
return callback(new Error('請輸入驗(yàn)證碼'))
}
setTimeout(() => {
if (value != code.value) {
callback(new Error('驗(yàn)證碼有誤,請重新輸入'))
}else {
callback()
}
}, 500)
}通過reactive函數(shù)創(chuàng)建了一個(gè)名為rules的響應(yīng)式對象,其中包含一個(gè)名為valicode的屬性,其值為一個(gè)數(shù)組,數(shù)組中包含兩個(gè)對象,分別表示對于valicode這個(gè)表單項(xiàng)的兩個(gè)驗(yàn)證規(guī)則。第一個(gè)規(guī)則要求該表單項(xiàng)必填,且在失去焦點(diǎn)時(shí)進(jìn)行驗(yàn)證;第二個(gè)規(guī)則使用了自定義的驗(yàn)證函數(shù)checkCode,在失去焦點(diǎn)時(shí)進(jìn)行驗(yàn)證。
checkCode函數(shù)接收三個(gè)參數(shù),分別為驗(yàn)證規(guī)則對象、當(dāng)前表單項(xiàng)的值和回調(diào)函數(shù)。在函數(shù)內(nèi)部,首先打印出了一個(gè)名為code的響應(yīng)式對象的值,然后判斷當(dāng)前表單項(xiàng)的值是否為空,如果為空則通過回調(diào)函數(shù)返回一個(gè)錯(cuò)誤信息。如果不為空,則通過setTimeout函數(shù)模擬了一個(gè)異步驗(yàn)證過程,500毫秒后判斷當(dāng)前表單項(xiàng)的值是否等于code的值,如果不等于則通過回調(diào)函數(shù)返回一個(gè)錯(cuò)誤信息,否則通過回調(diào)函數(shù)返回一個(gè)空值表示驗(yàn)證通過。
這里setTimeout函數(shù)給form標(biāo)簽加上status-icon會在校驗(yàn)時(shí)有一個(gè)轉(zhuǎn)圈的效果哦~
最終效果



到此這篇關(guān)于vue3+vite3+typescript實(shí)現(xiàn)驗(yàn)證碼功能及表單驗(yàn)證效果的文章就介紹到這了,更多相關(guān)vue3+vite3+typescript驗(yàn)證碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3結(jié)合typescript中使用class封裝axios
- 使用Vite+Vue3+TypeScript?搭建開發(fā)腳手架的詳細(xì)過程
- vue?props使用typescript自定義類型的方法實(shí)例
- 基于Vue3+TypeScript的全局對象的注入和使用詳解
- Vue3+TypeScript+Vite使用require動態(tài)引入圖片等靜態(tài)資源
- vue3+Pinia+TypeScript?實(shí)現(xiàn)封裝輪播圖組件
- Vue+TypeScript中處理computed方式
- vue項(xiàng)目中使用ts(typescript)入門教程
- vue3中如何使用vue-types
相關(guān)文章
vue3簡易實(shí)現(xiàn)proxy代理實(shí)例詳解
這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)學(xué)生成績管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03
vue自定義組件實(shí)現(xiàn)v-model雙向綁定數(shù)據(jù)的實(shí)例代碼
vue中父子組件通信,都是單項(xiàng)的,直接在子組件中修改prop傳的值vue也會給出一個(gè)警告,接下來就用一個(gè)小列子一步一步實(shí)現(xiàn)了vue自定義的組件實(shí)現(xiàn)v-model雙向綁定,需要的朋友可以參考下2021-10-10
vue+elementUI組件tree如何實(shí)現(xiàn)單選加條件禁用
這篇文章主要介紹了vue+elementUI組件tree如何實(shí)現(xiàn)單選加條件禁用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
ElementUI時(shí)間選擇器限制選擇范圍disabledData的使用
本文主要介紹了ElementUI時(shí)間選擇器限制選擇范圍disabledData的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
vue cli 3.x 項(xiàng)目部署到 github pages的方法
這篇文章主要介紹了vue cli 3.x 項(xiàng)目部署到 github pages的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-04-04

