vue 滑块组件 无需npm下载 直接使用

image.png

组件内容:
dragVerify.vue

<template>
  <div
    ref="dragVerify"
    class="drag_verify"
    :style="dragVerifyStyle"
    @mousemove="dragMoving"
    @mouseup="dragFinish"
    @mouseleave="dragFinish"
    @touchmove="dragMoving"
    @touchend="dragFinish"
  >

    <div
      class="dv_progress_bar"
      :class="{goFirst2:isOk}"
      ref="progressBar"
      :style="progressBarStyle"
    >

    </div>
    <div
      class="dv_text"
      :style="textStyle"
      ref="message"
    >
      <slot
        name="textBefore"
        v-if="$slots.textBefore"
      ></slot>
      {{message}}
      <slot
        name="textAfter"
        v-if="$slots.textAfter"
      ></slot>
    </div>

    <div
      class="dv_handler dv_handler_bg"
      :class="{goFirst:isOk}"
      @mousedown="dragStart"
      @touchstart="dragStart"
      ref="handler"
      :style="handlerStyle"
    >
      <i :class="handlerIcon"></i>
    </div>

  </div>
</template>
<script>
export default {
    name: 'dragVerify',
    props: {
        isPassing: {
            type: Boolean,
            default: false
        },
        width: {
            type: Number,
            default: 250
        },
        height: {
            type: Number,
            default: 40
        },
        text: {
            type: String,
            default: 'swiping to the right side'
        },
        successText: {
            type: String,
            default: 'success'
        },
        background: {
            type: String,
            default: '#eee'
        },
        progressBarBg: {
            type: String,
            default: '#76c61d'
        },
        completedBg: {
            type: String,
            default: '#76c61d'
        },
        circle: {
            type: Boolean,
            default: false
        },
        radius: {
            type: String,
            default: '4px'
        },
        handlerIcon: {
            type: String
        },
        successIcon: {
            type: String
        },
        handlerBg: {
            type: String,
            default: '#e8e8e8'
        },
        textSize: {
            type: String,
            default: '14px'
        },
        textColor: {
            type: String,
            default: '#333'
        }
    },
    mounted: function() {
        const dragEl = this.$refs.dragVerify;
        dragEl.style.setProperty('--textColor', this.textColor);
        dragEl.style.setProperty('--width', Math.floor(this.width / 2) + 'px');
        dragEl.style.setProperty('--pwidth', -Math.floor(this.width / 2) + 'px');
        console.log(this.$slots);
    },
    computed: {
        handlerStyle: function() {
            return {
                left: '0px',
                width: this.height + 'px',
                height: this.height + 'px',
                background: this.handlerBg
            };
        },
        message: function() {
            return this.isPassing ? this.successText : this.text;
        },
        dragVerifyStyle: function() {
            return {
                width: this.width + 'px',
                height: this.height + 'px',
                lineHeight: this.height + 'px',
                background: this.background,
                borderRadius: this.circle ? this.height / 2 + 'px' : this.radius
            };
        },
        progressBarStyle: function() {
            return {
                background: this.progressBarBg,
                height: this.height + 'px',
                borderRadius: this.circle
                    ? this.height / 2 + 'px 0 0 ' + this.height / 2 + 'px'
                    : this.radius
            };
        },
        textStyle: function() {
            return {
                height: this.height + 'px',
                width: this.width + 'px',
                fontSize: this.textSize
            };
        }
    },
    data() {
        return {
            isMoving: false,
            x: 0,
            isOk: false
        };
    },
    methods: {
        dragStart: function(e) {
            if (!this.isPassing) {
                this.isMoving = true;
                const handler = this.$refs.handler;
                this.x =
          (e.pageX || e.touches[0].pageX) -
          parseInt(handler.style.left.replace('px', ''), 10);
            }
            this.$emit('handlerMove');
        },
        dragMoving: function(e) {
            if (this.isMoving && !this.isPassing) {
                const _x = (e.pageX || e.touches[0].pageX) - this.x;
                const handler = this.$refs.handler;
                if (_x > 0 && _x <= this.width - this.height) {
                    handler.style.left = _x + 'px';
                    this.$refs.progressBar.style.width = _x + this.height / 2 + 'px';
                } else if (_x > this.width - this.height) {
                    handler.style.left = this.width - this.height + 'px';
                    this.$refs.progressBar.style.width =
            this.width - this.height / 2 + 'px';
                    this.passVerify();
                }
            }
        },
        dragFinish: function(e) {
            if (this.isMoving && !this.isPassing) {
                const _x = (e.pageX || e.changedTouches[0].pageX) - this.x;
                if (_x < this.width - this.height) {
                    this.isOk = true;
                    const that = this;
                    setTimeout(function() {
                        that.$refs.handler.style.left = '0';
                        that.$refs.progressBar.style.width = '0';
                        that.isOk = false;
                    }, 500);
                } else {
                    const handler = this.$refs.handler;
                    handler.style.left = this.width - this.height + 'px';
                    this.$refs.progressBar.style.width =
            this.width - this.height / 2 + 'px';
                    this.passVerify();
                }
                this.isMoving = false;
            }
        },
        passVerify: function() {
            this.$emit('update:isPassing', true);
            this.isMoving = false;
            const handler = this.$refs.handler;
            handler.children[0].className = this.successIcon;
            this.$refs.progressBar.style.background = this.completedBg;
            this.$refs.message.style['-webkit-text-fill-color'] = 'unset';
            this.$refs.message.style.animation = 'slidetounlock2 3s infinite';
            this.$refs.message.style.color = '#fff';
            this.$emit('passcallback');
        },
        reset: function() {
            const oriData = this.$options.data();
            for (const key in oriData) {
                if (oriData.hasOwnProperty(key)) {
                    this.$set(this, key, oriData[key]);
                }
            }
            const handler = this.$refs.handler;
            const message = this.$refs.message;
            handler.style.left = '0';
            this.$refs.progressBar.style.width = '0';
            handler.children[0].className = this.handlerIcon;
            message.style['-webkit-text-fill-color'] = 'transparent';
            message.style.animation = 'slidetounlock 3s infinite';
            message.style.color = this.background;
        }
    }
};
</script>
<style scoped>
.drag_verify {
  position: relative;
  background-color: #e8e8e8;
  text-align: center;
  overflow: hidden;
}
.drag_verify .dv_handler {
  position: absolute;
  top: 0px;
  left: 0px;
  cursor: move;
}
.drag_verify .dv_handler i {
  color: #666;
  padding-left: 0;
  font-size: 16px;
}
.drag_verify .dv_handler .el-icon-circle-check {
  color: #6c6;
  margin-top: 9px;
}
.drag_verify .dv_progress_bar {
  position: absolute;
  height: 34px;
  width: 0px;
}
.drag_verify .dv_text {
  position: absolute;
  top: 0px;
  color: transparent;
  -moz-user-select: none;
  -webkit-user-select: none;
  user-select: none;
  -o-user-select: none;
  -ms-user-select: none;
  background: -webkit-gradient(
    linear,
    left top,
    right top,
    color-stop(0, var(--textColor)),
    color-stop(0.4, var(--textColor)),
    color-stop(0.5, #fff),
    color-stop(0.6, var(--textColor)),
    color-stop(1, var(--textColor))
  );
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  -webkit-text-size-adjust: none;
  animation: slidetounlock 3s infinite;
}
.drag_verify .dv_text * {
  -webkit-text-fill-color: var(--textColor);
}
.goFirst {
  left: 0px !important;
  transition: left 0.5s;
}
.goFirst2 {
  width: 0px !important;
  transition: width 0.5s;
}
</style>
<style>
@-webkit-keyframes slidetounlock {
  0% {
    background-position: var(--pwidth) 0;
  }
  100% {
    background-position: var(--width) 0;
  }
}
@-webkit-keyframes slidetounlock2 {
  0% {
    background-position: var(--pwidth) 0;
  }
  100% {
    background-position: var(--pwidth) 0;
  }
}
</style>

父组件引用:

<drag-verify
      ref="dragVerify"
      :width="350"
      :height="40"
      progressBarBg="#FFA500"
      background="#F5F5F5"
      :isPassing.sync="isPassing"
      text="请按住滑块拖动"
      successText="验证通过"
      handlerIcon="el-icon-d-arrow-right"
      successIcon="el-icon-circle-check"
      @passcallback="passcallback2">
</drag-verify>

import dragVerify from '@/components/dragVerify.vue';// 滑动验证组件
components: {
        'drag-verify': dragVerify 
},
data() {
     return {
         isPassing: false, // 滑块验证状态
     };
},

// 滑块验证成功走的方法
passcallback2() {
      console.log('this.isPassing:', this.isPassing);
      setTimeout(() => {
          this.showVerifyDlg = false;
          // this.reset()
          this.submitInfo();
      }, 1000);
 },
// 重置滑块
reset() {
    console.log('重置滑块');
    this.isPassing = false;
    if (this.$refs.dragVerify !== undefined) {
      this.$refs.dragVerify.reset();
    }
},

另外附赠几个用得着的地址:
// vue解决手机端h5,拖拽滑动滑块,页面跟着滚动问题
https://blog.csdn.net/qq_42704945/article/details/123073291
// 中文版滑块验证git
https://github.com/yimijianfang/vue-drag-verify
// 英文版滑块验证git
https://github.com/AshleyLv/vue-drag-verify
// 其他滑块验证写法
https://www.jb51.net/article/239681.htm
// 移动端 触摸事件和mousedown、mouseup、click事件之间的关系
https://blog.csdn.net/muzidigbig/article/details/83276851

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容