ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

springboot+vue实现滑块验证登入

2021-01-20 00:00:45  阅读:120  来源: 互联网

标签:vue return springboot 滑块 res else item background type


1、功能效果演示

在这里插入图片描述

2、技术涉及

1、登入模块,前后端分离,通过axios进行代理请求整体基于springboot+vue+shiro实现
2、cli 3.4.1+vue 2.5.2

3、主要逻辑代码

  1. 登入页面
<template>
  <div class="login-wrap">
    <div class="ms-title">网欲音乐 后台管理登录</div>
    <div class="ms-login">
      <el-form :model="ruleForm" :rules="rules" ref="ruleForm">
        <el-form-item prop="username">
          <el-input v-model="ruleForm.username" placeholder="用户名"></el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input type="password" v-model="ruleForm.password" placeholder="密码"></el-input>
        </el-form-item>
        <!--滑块验证-->
        <el-form-item>
          <JcRange @successFun="onSuccessFun" />
        </el-form-item>

        <div class="login-btn">
          <el-button type="primary" :loading="loading" @click="submitForm">登录</el-button>
        </div>
      </el-form>
    </div>
  </div>
</template>

<script>
  import {mixin} from "../mixins/index";
  import JcRange from "../components/jcRange"
  import {getLoginStatus} from "../api/index";
  export default {
    mixins:[mixin],
    data: function(){
      return {
        loading: false,
        status: false,
        ruleForm:{
          username: "jack",
          password: "1234567"
        },
        rules:{
          username:[
            {required:true,message:"请输入用户名",trigger:"blur"}
          ],
          password:[
            {required:true,message:"请输入密码",trigger:"blur"}
          ]
        }
      };
    },
    methods:{
      // 监听滑块成功事件
      onSuccessFun(e) {
        this.status = e;
      },
      submitForm(){
        let params = new URLSearchParams();
        params.append("name",this.ruleForm.username);
        params.append("password",this.ruleForm.password);
        if (!this.status) {
          return this.$message.error("请按住滑块,拖动到最右边");
        }
        this.loading = true;
        getLoginStatus(params)
          .then((res) =>{
            console.log(res)
            this.loading = true;

            if(res.code == 1){
              console.log(res.data.user.userId)
              console.log(res.data.user.userImg)
              this.$store.commit('setUserId',res.data.user.userId);
              this.$store.commit('setUserName',res.data.user.userName);
              this.$store.commit('setUserImg',res.data.user.userImg);
              sessionStorage.setItem('userId',res.data.user.userId);
              sessionStorage.setItem('userName',this.ruleForm.username);
              sessionStorage.setItem('userImg',res.data.user.userImg);
              sessionStorage.setItem('access_token',res.token) //设置令牌
              this.$router.push("/Info");
              this.notify("登录成功","success");
            }else{
              this.notify("登录失败","error");
            }
          });
      }
    },
    components:{
      JcRange
    }
  }
</script>

<style scoped>
  .login-wrap {
    position: relative;
    background: url("../assets/img/background.jpg");
    background-attachment: fixed;
    background-position: center;
    background-size: cover;
    width: 100%;
    height: 100%;
  }
  .ms-title {
    position: absolute;
    top: 50%;
    width: 100%;
    margin-top: -230px;
    text-align: center;
    font-size: 30px;
    font-weight: 600;
    color: #fff;
  }
  .ms-login {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 300px;
    /*height: 160px;*/
    margin-left: -190px;
    margin-top: -150px;
    padding: 40px;
    border-radius: 5px;
    background: #fff;
  }
  .login-btn {
    text-align: center;
  }
  .login-btn button {
    width: 100%;
    height: 36px;
  }
</style>

2、滑块组件

<template>
    <div class="jc-component__range">
        <div class="jc-range" :class="rangeStatus ? 'success' : '' ">
            <div class="draggable_bg" ref="bg" :style="{ width: draggable }" ></div>
            <i @mousedown="rangeMove" :class="rangeStatus ? successIcon : startIcon "></i>
            {{rangeStatus ? successText :startText}}
        </div>
    </div>
</template>
<script>
export default {
  props: {
    //成功图标
    successIcon: {
      type: String,
      default: "el-icon-success"
    },
    //成功文字
    successText: {
      type: String,
      default: "验证通过"
    },
    //开始的图标
    startIcon: {
      type: String,
      default: "el-icon-d-arrow-right"
    },
    //开始的文字
    startText: {
      type: String,
      default: "请按住滑块,拖动到最右边"
    }
  },
  name: "Silder",
  data() {
    return {
      rangeStatus: "",
      draggable: 0
    };
  },
  methods: {
    rangeMove(e) {
      let ele = e.target;
      let startX = e.clientX;
      let eleWidth = ele.offsetWidth;
      let parentWidth = ele.parentElement.offsetWidth;
      let MaxX = parentWidth - eleWidth;
      if (this.rangeStatus) {
        //不运行
        return false;
      }
      document.onmousemove = e => {
        let endX = e.clientX;
        this.disX = endX - startX;
        if (this.disX <= 0) {
          this.disX = 0;
        }
        if (this.disX >= MaxX - eleWidth) {
          //减去滑块的宽度
          this.disX = MaxX;
        }
        this.$refs.bg.style.transition = ".0s all";
        this.draggable = this.disX + 'px'; // 滑块中的背景
        ele.style.transform = "translateX(" + this.disX + "px)";
        ele.style.transition = ".0s all";
        e.preventDefault();
      };
      document.onmouseup = () => {
        if (this.disX !== MaxX) {
          ele.style.transition = ".5s all";
          ele.style.transform = "translateX(0)";
          this.$refs.bg.style.transition = ".5s all";
          this.draggable = 0 + 'px'; // 滑块中的背景
          //执行成功的函数
          this.$emit("errorFun", false);
        } else {
          this.rangeStatus = true;
          this.draggable = 0; // 滑块中的背景
          //执行成功的函数
          this.$emit("successFun", true);
        }
        document.onmousemove = null;
        document.onmouseup = null;
      };
    }
  }
};
</script>
<style scoped>
.jc-range {
  background-color: #e8e8e8;
  position: relative;
  transition: 1s all;
  user-select: none;
  color: #333;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 45px;
  border-radius: 1px;
  z-index: 9999;
  /*no*/
}

.draggable_bg {
  position: absolute;
  left: 0;
  height: 100%; 
  background-color: #7ac23c;
  z-index: -1;
}

.jc-range i {
  position: absolute;
  left: 0;
  width: 60px;
  /*no*/
  height: 100%;
  color: #919191;
  background-color: #fff;
  border: 1px solid #bbb;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

.jc-range.success {
  background-color: #7ac23c;
  color: #fff;
  border-radius: 1px;
  z-index: 99999;
}

.jc-range.success i {
  color: #7ac23c;
}
</style>

3、后端接口主要代码

	@RequestMapping("/login")
    public Result login(HttpServletRequest request){
        String loginName = request.getParameter("name");
        String password = request.getParameter("password");
        request.getSession().setAttribute("loginName",loginName);
        System.out.println("我是登录页的"+request.getSession().getAttribute("loginName"));
        System.out.println(loginName+"---->"+password);
        UserToken token = new UserToken(LoginType.USER_PASSWORD, loginName, password);
        return shiroLogin(token,LoginType.USER_PASSWORD);
    }

*登入页面涉及的其他文件
1、index.js

export const mixin = {
    methods:{
        //提示信息
        notify(title,type){
            this.$notify({
                title: title,
                type: type
            })
        },
        //根据相对地址获取绝对地址
        getUrl(url){
            return `${this.$store.state.HOST}/static/images${url}`
        },
        //获取性别中文
        changeSex(value){
            if(value == 0){
                return '女';
            }
            if(value == 1){
                return '男';
            }
            if(value == 2){
                return '组合';
            }
            if(value == 3){
                return '不明';
            }
            return value;
        },
        //获取生日
        attachBirth(val){
            return String(val).substr(0,10);
        },
        //上传图片之前的校验
        beforeAvatorUpload(file){
            const isJPG = (file.type === 'image/jpeg')||(file.type === 'image/png');
            if(!isJPG){
                this.$message.error('上传头像图片只能是jpg或png格式');
                return false;
            }
            const isLt2M = (file.size / 1024 /1024) < 2;
            if(!isLt2M){
                this.$message.error('上传头像图片大小不能超过2MB');
                return false;
            }
            return true;
        },
        //上传图片成功之后要做的工作
        handleAvatorSuccess(res){
            let _this = this;
            if(res.code == 1){
                _this.getData();
                _this.$notify({
                    title: '上传成功',
                    type: 'success'
                });
            }else{
                _this.$notify({
                    title: '上传失败',
                    type: 'error'
                });
            }
        },
        //弹出删除窗口
        handleDelete(id){
            this.idx = id;
            this.delVisible = true;
        },
        //把已经选择的项赋值给multipleSelection
        handleSelectionChange(val){
            this.multipleSelection = val;
            console.log("this.multipleSelection---6757457--->"+this.multipleSelection)
        },
        //批量删除已经选择的项
        delAll(){

          this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {

            for(let item of this.multipleSelection){
              //console.log(item);
              if(item.userId!=undefined){
                this.handleDelete(item.userId);
                this.deleteRow();
              }else if(item.moveCategoryId!=undefined){
                this.handleDelete(item.moveCategoryId);
                this.deleteRow();

              }else if(item.moveId!=undefined){
                this.handleDelete(item.moveId);
                this.deleteRow();

              }
            else if(item.songListId!=undefined){
              this.handleDelete(item.songListId);
              this.deleteRow();

            }
              else if(item.musicCategoryId !=undefined){
                this.handleDelete(item.musicCategoryId );
                this.deleteRow();

              }
              else if(item.songerId != undefined && item.songerName!=undefined){
                this.handleDelete(item.songerId);
                this.deleteRow();

              }
              else if(item.musicId!=undefined && item.musicName !=undefined){
                this.handleDelete(item.musicId);
                this.deleteRow();

              }

              else{
                alert("客官!你还没来设置哦!")
              }
            }
            this.multipleSelection = [];
            this.$message({
              type: 'success',
              message: '删除成功!'
            });

          }).catch(() => {
            this.$message({
              type: 'info',
              message: '已取消删除'
            });
          });
        }
    }
}

2、登入接口API

// 判断管理员是否登录成功
export const getLoginStatus = (params) => post(`admin/login`,params);

对于后端接口由于涉及到shiro实现的多ream认证,所以打算在下期分享shiro实现用户名密码、手机号、短信验证登入。望谅解,如遇疑问欢迎大家留言!QQ: 2817670312

顺便可以关注微信公众号:幽灵邀请函 了解其他文章及疑问解答。

标签:vue,return,springboot,滑块,res,else,item,background,type
来源: https://blog.csdn.net/qq_43900677/article/details/112854749

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有