瀏覽代碼

滑块验证

ming 3 年之前
父節點
當前提交
0cbaa4c5fb
共有 2 個文件被更改,包括 171 次插入6 次删除
  1. 134 0
      src/views/login/JcRange.vue
  2. 37 6
      src/views/login/index.vue

+ 134 - 0
src/views/login/JcRange.vue

@@ -0,0 +1,134 @@
+<template>
+  <div class="jc-component__range">
+    <div class="jc-range" :class="rangeStatus?'success':''">
+      <i @mousedown="rangeMove" :class="rangeStatus?successIcon:startIcon"></i>
+      {{rangeStatus?successText:startText}}
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    // 成功之后的函数
+    successFun: {
+      type: Function
+    },
+    //成功图标
+    successIcon: {
+      type: String,
+      default: "el-icon-success"
+    },
+    //成功文字
+    successText: {
+      type: String,
+      default: "验证成功"
+    },
+    //开始的图标
+    startIcon: {
+      type: String,
+      default: "el-icon-d-arrow-right"
+    },
+    //开始的文字
+    startText: {
+      type: String,
+      default: "拖动滑块到最右边"
+    },
+    //失败之后的函数
+    errorFun: {
+      type: Function
+    },
+    //或者用值来进行监听
+    status: {
+      type: String
+    }
+  },
+  name: "Silder",
+  data() {
+    return {
+        rangeStatus:'',
+        
+    };
+  },
+  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;
+				}
+				ele.style.transition = '.1s all';
+				ele.style.transform = 'translateX('+this.disX+'px)';
+				e.preventDefault();
+			}
+			document.onmouseup = ()=> {
+				
+				if(this.disX !== MaxX){
+					alert('fail')
+					ele.style.transition = '.5s all';
+					ele.style.transform = 'translateX(0)';
+					this.rangeStatus = false;
+					//执行失败的函数
+					
+					this.errorFun && this.errorFun();
+				}else{
+					// alert('succc')
+					this.rangeStatus = true;
+					if(this.status){
+						this.$parent[this.status] = true;
+					}
+					//执行成功的函数
+					this.successFun && this.successFun();
+				}
+				document.onmousemove = null;
+				document.onmouseup = null;
+			}
+		}
+  
+  }
+};
+</script>
+<style scoped>
+    .jc-range{
+	background-color: #CCC;
+	position: relative;
+	transition: 1s all;
+	user-select: none;
+	color: #333;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	height: 45px; /*no*/
+}
+.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;
+}
+.jc-range.success{
+	background-color: #7AC23C;
+	color: #fff;
+}
+.jc-range.success i{
+	color: #7AC23C;
+}
+</style>

+ 37 - 6
src/views/login/index.vue

@@ -25,6 +25,15 @@
                 </template>
               </a-input>
             </a-form-item>
+
+            <a-form-item>
+              <JcRange
+              :status="status"
+                :successFun="onSuccess()"
+                :errorFun="onError()"
+              ></JcRange>
+            </a-form-item>
+
             <a-form-item>
               <a-button
                 type="primary"
@@ -51,11 +60,15 @@ import { mapActions, mapGetters } from 'vuex'
 import { useRouter } from 'vue-router'
 import { UserOutlined, LockOutlined } from '@ant-design/icons-vue'
 
+import JcRange from './JcRange.vue'
+// import { ElMessage } from 'element-plus'
+
 export default {
   name: 'Login',
   components: {
     UserOutlined,
     LockOutlined,
+    JcRange,
   },
   data() {
     return {
@@ -63,6 +76,7 @@ export default {
         username: '',
         password: '',
       },
+      status: false,
       redirect: undefined,
       dependencies: dependencies,
       devDependencies: devDependencies,
@@ -91,9 +105,6 @@ export default {
     if (router.currentRoute.value.query.userName === 'admin') {
       this.handleSubmit()
     }
-    // setTimeout(() => {
-    //   this.handleSubmit()
-    // }, 3000)
   },
   methods: {
     ...mapActions({
@@ -104,9 +115,28 @@ export default {
         ? '/'
         : this.redirect
     },
+    onSuccess() {
+      console.log('滑块成功')
+      this.status = true
+   
+    },
+    onError() {
+      console.log('滑块失败')
+      this.status = false
+    },
+
     async handleSubmit() {
-      await this.login(this.form)
-      await this.$router.push(this.handleRoute())
+       await this.login(this.form)
+        await this.$router.push(this.handleRoute())
+      // if (this.status) {
+      //   await this.login(this.form)
+      //   await this.$router.push(this.handleRoute())
+      // } else {
+      //   ElMessage({
+      //     message: '请先滑块验证',
+      //     type: 'warning',
+      //   })
+      // }
     },
   },
 }
@@ -119,7 +149,7 @@ export default {
   background-size: cover;
   &-form {
     width: calc(100% - 40px);
-    height: 380px;
+    height: 440px;
     padding: 4vh;
     margin-top: calc((100vh - 380px) / 2);
     margin-right: 20px;
@@ -160,3 +190,4 @@ export default {
   }
 }
 </style>
+l