用Element-Ui封装一个滑动组件


基于Element-Ui的“Slider滑块”组件封装一个前端滑动滑动验证组件

  • 主要用于登录验证
  • 纯前端验证(滑着过瘾)目前无法与后端进行校验
  • 封装还可以优化
  • 直接看代码吧

slider组件

// slider/index.vue'
<template>
  <div class="bar" ref="bar">
    <el-slider
      class="slider"
      ref="slider"
      v-model="value"
      :show-tooltip="false"
      @change="sliderChange"
      :disabled="sliderDisabled"
    ></el-slider>
    <div class="slider-text-before" ref="barText">
      <div :class="noReset?'run run-no-slider':'run'" v-if="!isSuccess">拖动滑块验证</div>
      <span v-else style="color:#fff;">验证通过</span>
    </div>
  </div>
</template>
<script>
export default {
  name: "slider",
  props: {
    reset: {
      type: Boolean,
      default: false
    },
    noReset: {
      type: Boolean,
      default: false,
    }
  },
  data() {
    return {
      value: 0,
      isSuccess: false,
      sliderDisabled: false
    };
  },
  watch: {
    reset: function(val) {
      if (val) {
        this.sliderReset();
      }
    },
    noReset(val){
      if(val){
        this.$refs.bar.classList.add("no-slider")
      }else{
        this.$refs.bar.classList.remove("no-slider")
      }
    },
    value(val){
      this.$emit("value",val)
    }
  },
  created() {
    },
  mounted() {
    console.log(this.$refs.slider.$refs.button1.$refs.button)


    // this.$refs.slider.$refs.button1.$refs.button.style = ""
    this.$refs.slider.$refs.button1.$refs.button.lastChild.innerHTML =
      "<i class='el-icon-d-arrow-right icon-arrow-right'></i>";

  },
  methods: {
    sliderChange(val) {
      if (val === 100) {
        this.sliderSucceed();
      } else {
        this.sliderReset();
      }
    },
    sliderSucceed() {
      this.isSuccess = true;
      this.$refs.slider.$refs.button1.$refs.button.lastChild.innerHTML =
        "<i class='el-icon-success icon-success'></i>";
      this.sliderDisabled = true;
      this.$emit("success", true);
    },
    sliderReset() {
      this.isSuccess = false;
      this.value = 0;
      this.sliderDisabled = false;
      this.$emit("update:reset", false);
      this.$refs.slider.$refs.button1.$refs.button.lastChild.innerHTML =
        "<i class='el-icon-d-arrow-right icon-arrow-right'></i>";
    }
  }
};
</script>
<style lang="scss" scoped>
$color: #67c23a;
// $color: #409EFF;
$slider_button_width: 60px;
$slider_button_height: 40px;
.bar {
  position: relative;
  width: 100%;
  background-color: #e4e7ed;
  border-radius: 3px;
  .slider-text-before {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    font-size: 16px;
    letter-spacing: 2px;
    user-select: none;
    .run {
      padding: 0 30px;
      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, #333),
        color-stop(0.3, #333),
        color-stop(0.5, #fff),
        color-stop(0.7, #333),
        color-stop(1, #333)
      );
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      -webkit-text-size-adjust: none;
      -webkit-animation: slidetounlock 3s infinite;
      animation: slidetounlock 3s infinite;
    }
    .run-no-slider{
      background: -webkit-gradient(
        linear,
        left top,
        right top,
        color-stop(0, #F56C6C),
        color-stop(0.3, #F56C6C),
        color-stop(0.5, #fff),
        color-stop(0.7, #F56C6C),
        color-stop(1, #F56C6C)
      );
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      -webkit-text-size-adjust: none;
      -webkit-animation: slidetounlock 3s infinite;
      animation: slidetounlock 3s infinite;
    }
  }
  .slider-text-after {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 10;
    color: #fff;
  }
  .slider {
    width: calc(100% - #{$slider_button_width});
    /deep/.el-slider__runway {
      margin: 0;
    }
    /deep/.el-slider__bar {
      height: 40px;
      background-color: $color;
      border-top-left-radius: 0px;
      border-bottom-left-radius: 0px;
    }
    /deep/.el-slider__runway {
      height: 40px;
    }
    /deep/.el-slider__button-wrapper {
      top: 0;
      width: $slider_button_width;
      height: 40px;
      margin-left: ($slider_button_width/2);
      :hover {
        transform: none;
      }
    }
    /deep/.el-slider__button {
      width: $slider_button_width;
      height: 40px;
      border-radius: 0;
      border-color: #dcdfe6;
      :hover {
        transform: none;
      }
    }
    /deep/.el-slider__button.dragging,
    .el-slider__button.hover,
    .el-slider__button:hover {
      -webkit-transform: none !important;
      transform: none !important;
    }
    /deep/.el-slider__runway.disabled .el-slider__button:hover {
      cursor: grab !important;
    }
    /deep/.icon-arrow-right {
      line-height: ($slider_button_height - 4px);
      font-size: 18px;
      color: #4c4c4c;
    }
    /deep/.icon-success {
      line-height: ($slider_button_height - 4px);
      font-size: 20px;
      color: $color;
    }
  }
}
@-webkit-keyframes slidetounlock {
  from {
    background-position: -70px 100%;
  }
  to {
    background-position: 80px 0;
  }
}
.no-slider{
  animation: shake 800ms ease-in-out;
}

@keyframes shake {
    10%, 90% { transform: translate3d(-1px, 0, 0); }
    20%, 80% { transform: translate3d(+2px, 0, 0); }
    30%, 70% { transform: translate3d(-4px, 0, 0); }
    40%, 60% { transform: translate3d(+4px, 0, 0); }
    50% { transform: translate3d(-4px, 0, 0); }
}
</style>

使用

// 引入
import slider from './slider'

// 使用
 <slider v-bind:reset.sync="isResetSlider" :noReset="isNoReset" @value="sliderValue" @success="sliderSuccess"></slider>

components:{
  slider
},
data() {
  return {
    isResetSlider: false,
    isSeccess: false,
    sliderVal: "",
    isNoReset: false
  };
}

methods: {
  // 滑动验证
  sliderSuccess(val){
    this.isSeccess = val
  },
  sliderValue(val){
    this.sliderVal = val
  },
  submitForm() {
    if(this.sliderVal == 0){
      this.isNoReset = true
      setTimeout(() => {
        this.isNoReset = false
      }, 900);
      return
    }
    if(this.isSeccess){
      console.log("submit");
      this.isResetSlider = true
      this.isSeccess = false
    }else{
      console.log("请滑动滑块验证");
    }
  }
}

效果截图

  • 滑动验证-未滑动

滑动验证-未滑动
滑动验证-未滑动

  • 滑动验证-滑动中

滑动验证-滑动中
滑动验证-滑动中

  • 滑动验证-滑动成功

滑动验证-滑动成功
滑动验证-滑动成功

  • 滑动验证GIF

滑动验证GIF
滑动验证GIF


  目录