美文网首页
前端验证码

前端验证码

作者: 李小白呀 | 来源:发表于2021-04-19 14:26 被阅读0次

    新建组件identify

    // 图片验证码
    <template>
      <div class="s-canvas">
        <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
      </div>
    </template>
    <script>
    export default {
      name: 'identify',
      props: {
        identifyCode: { // 默认注册码
          type: String,
          default: '1234'
        },
        fontSizeMin: { // 字体最小值
          type: Number,
          default: 20
        },
        fontSizeMax: { // 字体最大值
          type: Number,
          default: 27
        },
        backgroundColorMin: { // 验证码图片背景色最小值
          type: Number,
          default: 200
        },
        backgroundColorMax: { // 验证码图片背景色最大值
          type: Number,
          default: 220
        },
        dotColorMin: { // 背景干扰点最小值
          type: Number,
          default: 60
        },
        dotColorMax: { // 背景干扰点最大值
          type: Number,
          default: 120
        },
        contentWidth: { // 容器宽度
          type: Number,
          default: 64
        },
        contentHeight: { // 容器高度
          type: Number,
          default: 32
        }
      },
      methods: {
        // 生成一个随机数
        randomNum (min, max) {
          return Math.floor(Math.random() * (max - min) + min)
        },
        // 生成一个随机的颜色
        randomColor (min, max) {
          let r = this.randomNum(min, max)
          let g = this.randomNum(min, max)
          let b = this.randomNum(min, max)
          return 'rgb(' + r + ',' + g + ',' + b + ')'
        },
        drawPic () {
          let canvas = document.getElementById('s-canvas')
          let ctx = canvas.getContext('2d')
          ctx.textBaseline = 'bottom'
          // 绘制背景
          ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
          ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
          // 绘制文字
          for (let i = 0; i < this.identifyCode.length; i++) {
            this.drawText(ctx, this.identifyCode[i], i)
          }
          this.drawLine(ctx)
          this.drawDot(ctx)
        },
        drawText (ctx, txt, i) {
          ctx.fillStyle = this.randomColor(50, 160) // 随机生成字体颜色
          ctx.font = this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei' // 随机生成字体大小
          let x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1))
          let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
          var deg = this.randomNum(-30, 30)
          // 修改坐标原点和旋转角度
          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)
        },
        drawLine (ctx) {
          // 绘制干扰线
          for (let i = 0; i < 4; i++) {
            ctx.strokeStyle = this.randomColor(100, 200)
            ctx.beginPath()
            ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
            ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
            ctx.stroke()
          }
        },
        drawDot (ctx) {
          // 绘制干扰点
          for (let i = 0; i < 30; i++) {
            ctx.fillStyle = this.randomColor(0, 255)
            ctx.beginPath()
            ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
            ctx.fill()
          }
        }
      },
      watch: {
        identifyCode () {
          this.drawPic()
        }
      },
      mounted () {
        this.drawPic()
      }
    }
    </script>
     
    <style scoped>
    </style
    

    页面使用

    <template>
      <div class="login">
        <div class="loginBox">
          <div class="title">
          </div>
          <div class="login_title">
            <span class="logintitle">登录</span>
            <span
              class="signin"
              @click="signin"
            >注册</span>
          </div>
          <div class="loginInput">
            <el-form
              :model="loginForm"
              :rules="rules"
              class="loginForm"
              ref="loginFormRef"
            >
              <el-form-item prop="username">
                <el-input
                  prefix-icon="el-icon-mobile-phone"
                  placeholder="请输入您的手机号"
                  v-model="loginForm.username"
                ></el-input>
              </el-form-item>
              <el-form-item prop="password">
                <el-input
                  prefix-icon="el-icon-lock"
                  placeholder="请输入您的密码"
                  type="password"
                  v-model="loginForm.password"
                ></el-input>
              </el-form-item>
              <el-form-item prop="security">
                <el-input
                  prefix-icon="el-icon-document-checked"
                  placeholder="请输入图形校验码"
                  v-model="loginForm.security"
                ></el-input>
                <div
                  @click="changeCode()"
                  class="identify"
                >
                  <!-- 引入验证码组件 -->
                  <identify :identifyCode="identifyCode"></identify>
                </div>
              </el-form-item>
              <div class="bottom">
                <span @click="RetrievingAccount">找回账户</span>
                <span@click="forgetPassword">忘记密码</span@click=>
              </div>
              <el-form-item>
                <el-button
                  type="
                  primary"
                  @click="handleLogin"
                >登录</el-button>
              </el-form-item>
            </el-form>
    
          </div>
        </div>
      </div>
    </template>
    
    <script>
    // 引入验证码组件
    import identify from '../components/identify'
    export default {
      // 组件名称
      name: '',
      // 局部注册的组件
      components: { identify },
      // 组件参数 接收来自父组件的数据
      props: {},
      // 组件状态值
      data () {
        return {
          
          loginForm: {
            username: '',
            password: '',
            security: '',
    
          },
          rules: {
            username: [
              { required: true, message: '请输入您的手机号', trigger: 'blur' },
            ],
            password: [
              { required: true, message: '请输入您的密码', trigger: 'blur' }
            ],
            security: [
              { required: true, message: '请输入图形校验码', trigger: 'blur' }
            ]
          },
    
          // 验证码初始值
          identifyCode: '1234',
          // 验证码的随机取值范围
          identifyCodes: '1234567890'
        }
      },
      // 计算属性
      computed: {},
      // 侦听器
      watch: {},
      // 生命周期钩子   注:没用到的钩子请自行删除
      created () { },
      mounted () {
        // 刷新页面就生成随机验证码
        this.identifyCode = ''
        this.makeCode(this.identifyCodes, 4)
    
      },
      // 组件方法
      methods: {
        // 点击验证码刷新验证码
        changeCode () {
          this.identifyCode = ''
          this.makeCode(this.identifyCodes, 4)
        },
        // 生成一个随机整数  randomNum(0, 10) 0 到 10 的随机整数, 包含 0 和 10
        randomNum (min, max) {
          max = max + 1
          return Math.floor(Math.random() * (max - min) + min)
        },
        // 随机生成验证码字符串
        makeCode (data, len) {
          for (let i = 0; i < len; i++) {
            this.identifyCode += data[this.randomNum(0, data.length - 1)]
          }
          console.log(this.identifyCode);
        },
        signin () {
          console.log('注册');
        },
        // 登录
        handleLogin () {
          console.log(this.loginForm);
        },
        RetrievingAccount () {
          console.log('找回账户');
        },
        forgetPassword () {
          console.log('忘记密码');
        }
      }
    }
    </script>
    
    <style scoped lang="scss">
    
    </style>
    

    样式


    image.png
    image.png

    相关文章

      网友评论

          本文标题:前端验证码

          本文链接:https://www.haomeiwen.com/subject/vkpilltx.html