使用vue编写一个带有数字和字母图片校验弹出框

一:纯数字 校验

在Vue中创建一个包含随机验证码校验的弹出框,我们可以使用Vue的组件系统、数据绑定和事件处理功能。以下是一个简单的实现方式,包括一个名为CaptchaModal.vue的组件,该组件用于显示验证码、用户输入和校验逻辑

vue代码

<template>  
  <div v-if="visible" class="modal-overlay">  
    <div class="modal">  
      <span class="close" @click="close">&times;</span>  
      <p>验证码: {{ captcha }}</p>  
      <input type="text" v-model="userInput" placeholder="请输入验证码" @keyup.enter="checkCaptcha">  
      <button @click="checkCaptcha">校验</button>  
      <p v-if="errorMessage" class="error">{{ errorMessage }}</p>  
    </div>  
  </div>  
</template>  
  
<script>  
export default {  
  data() {  
    return {  
      visible: false,  
      captcha: '',  
      userInput: '',  
      errorMessage: ''  
    };  
  },  
  methods: {  
    open() {  
      this.visible = true;  
      this.generateCaptcha();  
      this.userInput = '';  
      this.errorMessage = '';  
    },  
    close() {  
      this.visible = false;  
    },  
    generateCaptcha() {  
      // 生成一个六位的随机验证码  
      this.captcha = Math.floor(100000 + Math.random() * 900000).toString();  
    },  
    checkCaptcha() {  
      if (this.userInput === this.captcha) {  
        this.errorMessage = ''; // 清除错误信息  
        alert('验证码正确!');  
        this.close(); // 关闭弹出框  
      } else {  
        this.errorMessage = '验证码错误,请重试。';  
      }  
    }  
  }  
};  
</script>  
  
<style scoped>  
.modal-overlay {  
  position: fixed;  
  top: 0;  
  left: 0;  
  width: 100%;  
  height: 100%;  
  background-color: rgba(0, 0, 0, 0.5);  
  display: flex;  
  justify-content: center;  
  align-items: center;  
}  
  
.modal {  
  background-color: #fefefe;  
  padding: 20px;  
  border: 1px solid #888;  
  width: 300px;  
  text-align: center;  
}  
  
.close {  
  float: right;  
  font-size: 28px;  
  font-weight: bold;  
  cursor: pointer;  
}  
  
.close:hover,  
.close:focus {  
  color: #000;  
  text-decoration: none;  
  cursor: pointer;  
}  
  
.error {  
  color: red;  
}  
</style>

在父组件中使用CaptchaModal

在你的Vue应用中的父组件(比如App.vue)中,你可以这样引入并使用CaptchaModal组件:

<template>  
  <div id="app">  
    <button @click="openCaptchaModal">打开验证码校验</button>  
    <CaptchaModal ref="captchaModal" />  
  </div>  
</template>  
  
<script>  
import CaptchaModal from './components/CaptchaModal.vue';  
  
export default {  
  components: {  
    CaptchaModal  
  },  
  methods: {  
    openCaptchaModal() {  
      this.$refs.captchaModal.open();  
    }  
  }  
};  
</script>  
  
<style>  
/* 可以在这里添加全局样式 */  
</style>

在这个例子中,CaptchaModal组件有一个visible数据属性来控制弹出框的显示与隐藏,一个captcha属性来存储生成的验证码,一个userInput属性来绑定用户输入的验证码,以及一个errorMessage属性来显示错误信息。通过openclose方法来控制弹出框的打开和关闭,generateCaptcha方法来生成新的验证码,checkCaptcha方法来校验用户输入的验证码是否正确。

在父组件中,我们通过ref属性给CaptchaModal组件实例命名(这里是captchaModal),然后通过this.$refs.captchaModal.open()来调用CaptchaModal组件的open方法,从而打开验证码校验的弹出框。

二:字母数字混合 校验

在上面的方法中已经实现了纯数字校验,要实现和大多数应用中一样的带有背景的不规则数字校验可以使用canvas 画图的方式来实现

主要代码如下:

<template>  
  <view class="content">  
    <canvas canvas-id="captchaCanvas" style="width: 100px; height: 40px;"></canvas>  
    <input type="text" v-model="inputCaptcha" placeholder="请输入验证码" />  
    <button @click="validateCaptcha">验证</button>  
  </view>  
</template>  
  
<script>  
export default {  
  data() {  
    return {  
      captchaText: '', // 存储生成的验证码文本  
      inputCaptcha: '' // 用户输入的验证码  
    };  
  },  
  methods: {  
    generateCaptcha() {  
      // ... 生成验证码并更新 captchaText 的代码 ...  
      // 注意:这里应该包含绘制验证码到 canvas 的代码,但为了简洁,我省略了它  
      // 生成验证码文本并存储  
      const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';  
      let captcha = '';  
      for (let i = 0; i < 4; i++) {  
        captcha += chars.charAt(Math.floor(Math.random() * chars.length));  
      }  
      this.captchaText = captcha;  
      // 假设这里你已经调用了绘制验证码到 canvas 的方法  
    },  
    validateCaptcha() {  
      // 验证用户输入的验证码是否与生成的验证码一致  
      if (this.inputCaptcha === this.captchaText) {  
        uni.showToast({  
          title: '验证码正确',  
          icon: 'success'  
        });  
        // 这里可以添加验证码正确后的处理逻辑  
      } else {  
        uni.showToast({  
          title: '验证码错误',  
          icon: 'none'  
        });  
        // 可以选择重新生成验证码  
        // this.generateCaptcha();  
      }  
    }  
  },  
  mounted() {  
    // 页面加载完成后生成初始验证码  
    this.generateCaptcha();  
  }  
};  
</script>  
  
<style>  
/* 你的样式 */  
</style>

this.captchaText = captcha;  是保存carous 绘制内容用于验证 canvas 

uni-app 代码

<template>  
  <view class="captcha-page">  
    <view class="captcha-container">  
      <text class="captcha-text">验证码:</text>  
      <text class="captcha-value">{{ captcha }}</text>  
      <button @click="generateCaptcha" class="captcha-btn">刷新</button>  
      <input type="number" v-model="userInput" placeholder="请输入验证码" class="input-captcha" />  
      <button @click="checkCaptcha" class="check-btn">校验</button>  
      <text v-if="errorMessage" class="error-message">{{ errorMessage }}</text>  
    </view>  
  </view>  
</template>  
  
<script>  
export default {  
  data() {  
    return {  
      captcha: '',  
      userInput: '',  
      errorMessage: ''  
    };  
  },  
  methods: {  
    generateCaptcha() {  
      this.captcha = Math.floor(100000 + Math.random() * 900000).toString();  
      this.userInput = '';  
      this.errorMessage = '';  
    },  
    checkCaptcha() {  
      if (this.userInput === this.captcha) {  
        uni.showToast({ title: '验证码校验成功!', icon: 'success' });  
        // 这里可以添加其他成功后的逻辑,如关闭页面、跳转等  
      } else {  
        this.errorMessage = '验证码错误,请重试。';  
      }  
    }  
  },  
  mounted() {  
    this.generateCaptcha(); // 组件挂载后生成初始验证码  
  }  
};  
</script>  
  
<style scoped>  
.captcha-page {  
  display: flex;  
  justify-content: center;  
  align-items: center;  
  height: 100%;  
  padding: 20px;  
  box-sizing: border-box;  
}  
  
.captcha-container {  
  background-color: #fff;  
  border-radius: 8px;  
  padding: 20px;  
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);  
  width: 80%;  
  max-width: 400px;  
  text-align: center;  
}  
  
.captcha-text {  
  font-size: 16px;  
  color: #333;  
  margin-bottom: 10px;  
}  
  
.captcha-value {  
  font-size: 24px;  
  color: #f44336;  
  margin-bottom: 20px;  
}  
  
.captcha-btn {  
  padding: 8px 16px;  
  background-color: #007aff;  
  color: #fff;  
  border: none;  
  border-radius: 4px;  
  cursor: pointer;  
  margin-top: 10px;  
}  
  
.input-captcha {  
  padding: 10px;  
  margin-bottom: 10px;  
  border: 1px solid #ccc;  
  border-radius: 4px;  
  width: 100%;  
  box-sizing: border-box;  
}  
  
.check-btn {  
  padding: 10px 20px;  
  background-color: #4CAF50;  
  color: white;  
  border: none;  
  border-radius: 4px;  
  cursor: pointer;  
}  
  
.error-message {  
  color: red;  
  font-size: 14px;  
}  
</style>

如果你遇到了在 uni-app 中界面已经显示完毕但 canvas 还没有显示内容的问题,尽管实际上内容已经绘制完成,这通常可能是由于以下几个原因造成的:

  1. 绘制时机问题:如果你在组件的 mounted 钩子中立即绘制 canvas,但此时 DOM 可能还没有完全准备好,尤其是当 canvas 元素位于条件渲染(如 v-if)或异步数据渲染的上下文中时。

  2. 绘制代码执行位置:确保你的绘制代码在 canvas 元素确实存在于 DOM 中之后执行。如果绘制代码在 canvas 元素被添加到 DOM 之前执行,那么它将不会生效。

  3. 页面渲染优化:有时浏览器的渲染优化可能会延迟某些 DOM 的绘制,特别是当它们不在视口内或刚被添加到 DOM 中时。

  4. uni.createCanvasContext 的使用:确保你正确地使用了 uni.createCanvasContext 方法,并且传递了正确的 canvas-id

  5. 异步操作:如果你的验证码生成涉及到异步操作(如从服务器获取某些数据),那么你可能需要确保在异步操作完成后才进行绘制。

我使用的定时器来延迟图片绘制的时间

mounted() {  
  setTimeout(() => {  
    this.generateCaptcha();  
  }, 500); // 延迟 500 毫秒  
},

效果图:

本文只提供基础的css样式 具体的css样式可以根据自己的需求更改

上图效果的全部代码在另一篇文章链接:在 uni-app 中使用 canvas 绘制验证码图片或者纯数字验证吗-CSDN博客

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值