最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue3 生成图片验证码组件

    正文概述 掘金(李西甲)   2021-03-28   938

    突然用到图片验证码,从其他论坛上东拼西凑出本地前端生成验证码图片的组件,做一下笔记。

    1、安装依赖

    需要用到【identify】和【md5】

    其中【md5】主要的作用是用于验证码正确值加密使用

    npm install identify
    npm install md5
    

    2、组件部分

    此处使用到canvas

    <template>
     <div class="s-canvas">
      <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
     </div>
    </template>
    
    
    <script>
    	import md5 from 'js-md5'
    	import {
    		toRefs,
    		onMounted,
    		watch,
    		defineComponent
    	} from 'vue'
    
    	export default defineComponent({
    		name: 'imageCode',
    		props: {
    			change: { // 刷新验证码使用
    				type: Boolean,
    				default: false
    			},
    			contentWidth: { // 验证码图片宽
    				type: Number,
    				default: 112
    			},
    			contentHeight: { // 验证码图片高
    				type: Number,
    				default: 38
    			}
    		},
    		emits: ["getCode"], // 返回验证码加密正确值的函数
    		setup(props, context) {
                            // 默认值 
    			const defaultData = {
    				identifyCode: '', // 验证码值,未加密的
    				identifyCodes: '1234567890', // 生成验证码的元素,可以加入字母
    				fontSizeMin: 20, // 图片上验证文字的最小值
    				fontSizeMax: 40, // 图片上验证文字的最小值
    				backgroundColorMin: 180, // 图片背景色值最小
    				backgroundColorMax: 240, // 图片背景色值最大
    				colorMin: 50, // 文字色值最小
    				colorMax: 160, // 文字色值最大
    				lineColorMin: 40, // 干扰线色值最小
    				lineColorMax: 120, // 干扰线色值最大
    				dotColorMin: 0, // 干扰点色值最小
    				dotColorMax: 255, // 干扰点色值最大
                                    lineSum: 4, // 干扰线数量
                                    dotSum: 40, // 干扰点数量
    			}
                            // 父级传递
    			const {
    				contentWidth,
    				contentHeight,
    				change
    			} = toRefs(props)
    
    			// 生成一个随机数
    			const randomNum = (min, max) => {
    				return Math.floor(Math.random() * (max - min) + min)
    			}
    
    			// 生成一个随机的颜色
    			const randomColor = (min, max) => {
    				let r = randomNum(min, max)
    				let g = randomNum(min, max)
    				let b = randomNum(min, max)
    				return 'rgb(' + r + ',' + g + ',' + b + ')'
    			}
    
    			// 创建图形
    			const drawPic = () => {
    				let canvas = document.getElementById('s-canvas')
    				let ctx = canvas.getContext('2d')
    				ctx.textBaseline = 'bottom'
    				// 绘制背景
    				ctx.fillStyle = randomColor(defaultData.backgroundColorMin, defaultData.backgroundColorMax)
    				ctx.fillRect(0, 0, contentWidth.value, contentHeight.value)
    				// 绘制文字
    				for (let i = 0; i < defaultData.identifyCode.length; i++) {
    					drawText(ctx, defaultData.identifyCode[i], i)
    				}
    				drawLine(ctx)
    				drawDot(ctx)
    			}
    
    			// 绘制文字
    			const drawText = (ctx, txt, i) => {
    				ctx.fillStyle = randomColor(defaultData.colorMin, defaultData.colorMax)
    				ctx.font = randomNum(defaultData.fontSizeMin, defaultData.fontSizeMax) + 'px SimHei'
    				let x = (i + 1) * (contentWidth.value / (defaultData.identifyCode.length + 1))
    				let y = randomNum(defaultData.fontSizeMax, contentHeight.value - 5)
    				var deg = randomNum(-45, 45)
    				// 修改坐标原点和旋转角度
    				ctx.translate(x, y)
    				ctx.rotate(deg * Math.PI / 180)
    				ctx.fillText(txt, 0, 0)
    				// 恢复坐标原点和旋转角度
    				ctx.rotate(-deg * Math.PI / 180)
    				ctx.translate(-x, -y)
    			}
    
    			// 绘制干扰线
    			const drawLine = (ctx) => {
    				for (let i = 0; i < 4; i++) {
    					ctx.strokeStyle = randomColor(defaultData.lineColorMin, defaultData.lineColorMax)
    					ctx.beginPath()
    					ctx.moveTo(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value))
    					ctx.lineTo(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value))
    					ctx.stroke()
    				}
    			}
    			// 绘制干扰点
    			const drawDot = (ctx) => {
    				for (let i = 0; i < 60; i++) {
    					ctx.fillStyle = randomColor(0, 255)
    					ctx.beginPath()
    					ctx.arc(randomNum(0, contentWidth.value), randomNum(0, contentHeight.value), 1, 0, 2 * Math
    						.PI)
    					ctx.fill()
    				}
    			}
    
    			// 生成图片
    			const makeCode = () => {
    				defaultData.identifyCode = "";
    				for (let i = 0; i < 4; i++) {
    					defaultData.identifyCode += defaultData.identifyCodes[
    						randomNum(0, defaultData.identifyCodes.length)
    					];
    				}
                                    
                                    // 绘制图片
    				drawPic()
                                    // 返回加密后的图片验证码值
    				context.emit('getCode', md5(defaultData.identifyCode))
    			}
                            
                            // 初识函数,生成图片 
    			onMounted(() => {
    				makeCode()
    			})
    
                            // 监听change变化,重新生成图片
    			watch(change, () => {
    				makeCode()
    			})
    
    		}
    	})
    </script>
    

    3、调用组件

    1、引入组件
    import imageCode from '../../../components/ImageCode.vue';
    
    2、使用
    <image-code :change="data.change_img_code" @click="changeImageCode" @getCode="backImageCode"></image-code>
    
    3、script
    
    	export default {
    		name: '',
    		components: {
    			imageCode
    		},
    		setup(){
    			const data = reactive({
    				change_img_code: false, // 刷新验证码
    				img_code:'',// 加密后的验证码值
    			})
                            
                            // 刷新验证码操作
    			const changeImageCode = ()=> {
    				data.change_img_code = !data.change_img_code
    			}
    			
                            // 接收组件返回加密后的验证码值
    			const backImageCode = (code) =>{
    				data.img_code = code
    				console.log('data',data.img_code)
    			}
    			
    			return {
    				changeImageCode,
    				backImageCode,
    				data
    			}
    		}
    	}
    
    

    起源地下载网 » Vue3 生成图片验证码组件

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元