zoukankan      html  css  js  c++  java
  • vue登录页+验证码+MD5加密

    一,验证码功能
    1,创建一个组件。显示验证码图片

    <template>
     <div class="s-canvas">
      <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
     </div>
    </template>
    <script>
    export default{
     name: 'SIdentify',
     props: {
      identifyCode: { // 默认注册码
       type: String,
       default: '1234'
      },
      fontSizeMin: { // 字体最小值
       type: Number,
       default: 25
      },
      fontSizeMax: { // 字体最大值
       type: Number,
       default: 35
      },
      backgroundColorMin: { // 验证码图片背景色最小值
       type: Number,
       default: 200
      },
      backgroundColorMax: { // 验证码图片背景色最大值
       type: Number,
       default: 220
      },
      dotColorMin: { // 背景干扰点最小值
       type: Number,
       default: 60
      },
      dotColorMax: { // 背景干扰点最大值
       type: Number,
       default: 120
      },
      contentWidth: { // 容器宽度
       type: Number,
       default: 90
      },
      contentHeight: { // 容器高度
       type: Number,
       default: 38
      }
     },
     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 = '#e6ecfd'
       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>

    2,在登录页面中 验证码输输入框

    <el-form-item prop="verificationCode">
      <el-input type="text" v-model="loginForm.verificationCode" placeholder="- - - -">
       <template slot="prepend">验证码</template>
       <template slot="append">
        <div class="login-code" @click="refreshCode">
         <Identify :identifyCode="identifyCode"></Identify>
        </div>
       </template>
      </el-input>
     </el-form-item>
    
    //引入验证码组件
    import Identify from './identify'

    3,登录按钮

    <el-button-group>
            <el-button style="100%" @click="handleLogin" type="primary">登录</el-button>
     </el-button-group>

    4,在data中

    data() {
        const validateUsername = (rule, value, callback) => {
          if (!value) {
            callback(new Error("请输入用户名"));
          } else {
            callback();
          }
        };
        const validatePassword = (rule, value, callback) => {
          if (!value) {
            callback(new Error("请输入密码"));
          } else {
            callback();
          }
        };
        const validateCode = (rule, value, callback) => {
          if (value.toLowerCase() !== this.identifyCode.toLowerCase()) {
            this.refreshCode();
            callback(new Error("请填写正确验证码"));
          } else {
            callback();
          }
        };
        return {
          loginForm: {
            username: "",
            password: "",
            verificationCode: ""
          },
          loginRules: {
            username: [
              { required: true, trigger: "blur", validator: validateUsername }
            ],
            password: [
              { required: true, trigger: "blur", validator: validatePassword }
            ],
            verificationCode: [
              { required: true, trigger: "blur", validator: validateCode }
            ]
          },
          passwordType: "password",
          capsTooltip: false,
          loading: false,
          identifyCodes: "1234567890abcdefjhijklinopqrsduvwxyz",
          identifyCode: ""
        };
      },

    5,在mounted中

    mounted () {
      // 初始化验证码
      this.identifyCode = ''
      this.makeCode(this.identifyCodes, 4)
     },

    6,在method中

        //验证码事件
        refreshCode() {
          this.identifyCode = "";
          this.makeCode(this.identifyCodes, 4);
        },
        makeCode(o, l) {
          for (let i = 0; i < l; i++) {
            this.identifyCode += this.identifyCodes[
              this.randomNum(0, this.identifyCodes.length)
            ];
          }
        },
        randomNum(min, max) {
          return Math.floor(Math.random() * (max - min) + min);
        },
      //登录事件
      hhandleLogin(formName) {
          let paramt = {
            username: this.loginForm.username,
            password: this.$md5(this.loginForm.password)
          };
    
          this.$refs.loginForm.validate(valid => {
            if (valid) {
              this.loading = true;
              this.$store.dispatch("Login/getLogin", paramt).then(res => {
                let userList = res.data.data;
                sessionStorage.setItem("token", res.data.data.token);
                //vuex中的数据刷新页面会消失
                this.$router.push("/layout");
                this.loading = false;
              })
              .catch(() => {
                  this.loading = false;
                });
            } else {
              console.log("error submit!!");
              return false;
            }
          });
        },

    二,MD5加密
    1、npm安装

    npm install --save js-md5

    2,第一种使用方法

    在需要使用的项目文件中引入:
    import md5 from 'js-md5';
        
    使用:
    md5('mima')//612341288a285f5b188163482320e88f

    3,第二种使用方法

    在main.js文件中将md5转换成vue原型:
        import md5 from 'js-md5';
        Vue.prototype.$md5 = md5;
    
        在需要用到的文件中使用:
        this.$md5('mima')//612341288a285f5b188163482320e88f

    最后附登录页完整代码

    <template>
      <div class="login-container">
        <nav></nav>
        <main>
          <div class="main-l"></div>
          <div class="main-r">
            <img src="../../assets/image/l-t.png" alt />
            <div class="form-login">
              <el-form
                ref="loginForm"
                :model="loginForm"
                :rules="loginRules"
                class="login-form"
                autocomplete="on"
                label-position="left"
              >
                <el-form-item prop="username">
                  <span class="svg-container">
                    <i class="el-icon-user"></i>
                  </span>
                  <el-input
                    ref="username"
                    v-model="loginForm.username"
                    placeholder="请输入用户名"
                    name="username"
                    type="text"
                    tabindex="1"
                    autocomplete="on"
                  />
                </el-form-item>
    
                <el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
                  <el-form-item prop="password">
                    <span class="svg-container">
                      <i class="el-icon-lock"></i>
                    </span>
                    <el-input
                      :key="passwordType"
                      ref="password"
                      v-model="loginForm.password"
                      :type="passwordType"
                      placeholder="请输入密码"
                      name="password"
                      tabindex="2"
                      autocomplete="on"
                      @keyup.native="checkCapslock"
                      @blur="capsTooltip = false"
                      @keyup.enter.native="handleLogin"
                    />
                    <span class="show-pwd" @click="showPwd">
                      <i
                        :class="passwordType === 'password' ? 'iconfont zhzyguanbi-yanjing' : 'el-icon-view'"
                      ></i>
                    </span>
                  </el-form-item>
                </el-tooltip>
                <el-form-item prop="verificationCode">
                  <span class="svg-container">
                    <i class="el-icon-key"></i>
                  </span>
                  <el-input
                    ref="verificationCode"
                    v-model="loginForm.verificationCode"
                    placeholder="请输入验证码"
                    name="verificationCode"
                    type="text"
                    tabindex="1"
                    autocomplete="on"
                  >
                    <template slot="append">
                      <div class="login-code" @click="refreshCode">
                        <Identify :identifyCode="identifyCode"></Identify>
                      </div>
                    </template>
                  </el-input>
                </el-form-item>
                <el-button
                  :loading="loading"
                  type="primary"
                  style="100%;height:60px;font-size:20px"
                  @click.native.prevent="handleLogin"
                >立即登录</el-button>
              </el-form>
            </div>
          </div>
        </main>
      </div>
    </template>
    
    <script>
    import Identify from "../../components/VerificationCode/VerificationCode";
    import { login } from "../../api/login";
    import { mapActions } from "vuex";
    export default {
      name: "Login",
      components: { Identify },
      data() {
        const validateUsername = (rule, value, callback) => {
          if (!value) {
            callback(new Error("请输入用户名"));
          } else {
            callback();
          }
        };
        const validatePassword = (rule, value, callback) => {
          if (!value) {
            callback(new Error("请输入密码"));
          } else {
            callback();
          }
        };
        const validateCode = (rule, value, callback) => {
          if (value.toLowerCase() !== this.identifyCode.toLowerCase()) {
            this.refreshCode();
            callback(new Error("请填写正确验证码"));
          } else {
            callback();
          }
        };
        return {
          loginForm: {
            username: "",
            password: "",
            verificationCode: ""
          },
          loginRules: {
            username: [
              { required: true, trigger: "blur", validator: validateUsername }
            ],
            password: [
              { required: true, trigger: "blur", validator: validatePassword }
            ],
            verificationCode: [
              { required: true, trigger: "blur", validator: validateCode }
            ]
          },
          passwordType: "password",
          capsTooltip: false,
          loading: false,
          identifyCodes: "1234567890abcdefjhijklinopqrsduvwxyz",
          identifyCode: ""
        };
      },
      created() {},
      mounted() {
        if (this.loginForm.username === "") {
          this.$refs.username.focus();
        } else if (this.loginForm.password === "") {
          this.$refs.password.focus();
        }
        // 初始化验证码
        this.identifyCode = "";
        this.makeCode(this.identifyCodes, 4);
      },
      methods: {
        checkCapslock({ shiftKey, key } = {}) {
          if (key && key.length === 1) {
            if (
              (shiftKey && (key >= "a" && key <= "z")) ||
              (!shiftKey && (key >= "A" && key <= "Z"))
            ) {
              this.capsTooltip = true;
            } else {
              this.capsTooltip = false;
            }
          }
          if (key === "CapsLock" && this.capsTooltip === true) {
            this.capsTooltip = false;
          }
        },
        showPwd() {
          if (this.passwordType === "password") {
            this.passwordType = "";
          } else {
            this.passwordType = "password";
          }
          this.$nextTick(() => {
            this.$refs.password.focus();
          });
        },
       handleLogin(formName) {
          let paramt = {
            username: this.loginForm.username,
            password: this.$md5(this.loginForm.password)
          };
    
          this.$refs.loginForm.validate(valid => {
            if (valid) {
              this.loading = true;
              this.$store.dispatch("Login/getLogin", paramt).then(res => {
                let userList = res.data.data;
                sessionStorage.setItem("token", res.data.data.token);
                //vuex中的数据刷新页面会消失
                this.$router.push("/layout");
                this.loading = false;
              })
              .catch(() => {
                  this.loading = false;
                });
            } else {
              console.log("error submit!!");
              return false;
            }
          });
        },
        //验证码事件
        refreshCode() {
          this.identifyCode = "";
          this.makeCode(this.identifyCodes, 4);
        },
        makeCode(o, l) {
          for (let i = 0; i < l; i++) {
            this.identifyCode += this.identifyCodes[
              this.randomNum(0, this.identifyCodes.length)
            ];
          }
        },
        randomNum(min, max) {
          return Math.floor(Math.random() * (max - min) + min);
        }
      }
    };
    </script>
    
    <style lang="scss">
    /* 修复input 背景不协调 和光标变色 */
    /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
    
    $bg: #283443;
    $light_gray: #fff;
    $cursor: #fff;
    
    @supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
      .login-container .el-input input {
        color: $cursor;
      }
    }
    
    /* reset element-ui css */
    .login-container {
      .el-input {
        display: inline-block;
        height: 47px;
        width: 85%;
    
        input {
          background: transparent;
          border: 0px;
          -webkit-appearance: none;
          border-radius: 0px;
          padding: 12px 5px 12px 15px;
          color: $light_gray;
          height: 47px;
          caret-color: $cursor;
    
          &:-webkit-autofill {
            box-shadow: 0 0 0px 1000px $bg inset !important;
            -webkit-text-fill-color: $cursor !important;
          }
        }
      }
    
      .el-form-item {
        border: 1px solid rgba(255, 255, 255, 0.1);
        background: rgba(0, 0, 0, 0.1);
        border-radius: 5px;
        color: #454545;
      }
      nav {
        width: 555px;
        height: 80px;
        background: pink;
        margin: 0 auto;
        margin-top: 150px;
        margin-bottom: 30px;
        background: url("../../assets/image/login-text.png") center no-repeat;
      }
      main {
        width: 910px;
        height: 505px;
        background: url("../../assets/image/l-code.png") center no-repeat;
        margin: 0 auto;
        display: flex;
        .main-l {
          width: 390px;
          height: 505px;
        }
        .main-r {
          width: 520px;
          height: 505px;
          padding: 50px 60px 0 55px;
          box-sizing: border-box;
          .form-login {
            margin-top: 30px;
          }
          .login-code {
            width: 90px;
            background: rgda(0, 0, 0, 0.6);
          }
        }
      }
    }
    </style>
    
    <style lang="scss" scoped>
    $bg: #2d3a4b;
    $dark_gray: #889aa4;
    $light_gray: #eee;
    
    .login-container {
      width: 100%;
      min-height: calc(100vh);
      background: url("../../assets/image/l-bge.png") center no-repeat;
      overflow: hidden;
    
      .login-form {
        position: relative;
        width: 520px;
        max-width: 100%;
        margin: 0 auto;
        overflow: hidden;
      }
    
      .tips {
        font-size: 14px;
        color: #fff;
        margin-bottom: 10px;
    
        span {
          &:first-of-type {
            margin-right: 16px;
          }
        }
      }
    
      .svg-container {
        padding: 6px 5px 6px 15px;
        color: $dark_gray;
        vertical-align: middle;
        width: 30px;
        display: inline-block;
      }
    
      .title-container {
        position: relative;
    
        .title {
          font-size: 26px;
          color: $light_gray;
          margin: 0px auto 40px auto;
          text-align: center;
          font-weight: bold;
        }
      }
    
      .show-pwd {
        position: absolute;
        right: 10px;
        top: 7px;
        font-size: 16px;
        color: $dark_gray;
        cursor: pointer;
        user-select: none;
      }
    
      .thirdparty-button {
        position: absolute;
        right: 0;
        bottom: 6px;
      }
    
      @media only screen and (max- 470px) {
        .thirdparty-button {
          display: none;
        }
      }
    }
    </style>
    <style lang="scss">
    .form-login .el-input-group__append {
      background: rgba(0, 0, 0, 0.3);
      padding: 0;
      left: 260px;
      bottom: 44px;
    }
    </style>

    转自:https://blog.csdn.net/LONGLONGAGO_RU/article/details/103908405

    在需要使用的项目文件中引入: import md5 from 'js-md5'; 使用: md5('mima')//612341288a285f5b188163482320e88f

  • 相关阅读:
    hdu 4135 Co-prime (容斥定理)
    hdu 1509 Windows Message Queue (优先队列)
    poj 2104 K-th Number (划分树)
    hdu 1556 Color the ball (树状数组)
    海量大数据大屏分析展示一步到位:DataWorks数据服务对接DataV最佳实践
    使用MaxCompute Java SDK运行安全相关命令
    使用MaxCompute Java SDK 执行任务卡住了,怎么办?
    老代码多=过度耦合=if else?阿里巴巴工程师这样捋直老代码
    日志服务Python消费组实战(三):实时跨域监测多日志库数据
    如何限制用户仅通过HTTPS方式访问OSS?
  • 原文地址:https://www.cnblogs.com/panchanggui/p/15003967.html
Copyright © 2011-2022 走看看