十分钟就能写好一个switch组件,它不香吗

294 阅读1分钟

之前看过许多许多组件都喜欢使用input来编写swich组件,实际不需要那么复杂,用自定义v-model也可以完美解决,还可以减少DOM结构。switch组件就是一个圆角矩形和一个小圆球一左一右配合就能简单实现。好的废话不多说。直接效果图。自定义的功能大家随意增加即可!写法上不一定好,仅供大家参考!

动画.gif

<template>

  <div>
    <span :class="[value?'switch-content active':'switch-content',disabled?'disabled':'']" @click="handleSwitch()">
      <span v-if="showText" :class="[value?'switch-text active':'switch-text']">{{ value ? '开' : '关' }}</span><span
        :class="[value?'switch-bar active':'switch-bar']">
      <span v-if="loading">
      <i :class="[loading?`loading`:'']">
      </i>
    </span>
    </span>
    </span>
  </div>

</template>

<script>
export default {
  name: "index",
  model: {
    prop: 'switchValue',
    event: 'change'
  },
  props: {
    switchValue: {
      type: Boolean
    },
    disabled: {
      type: Boolean
    },
    loading: {
      type: Boolean

    },
    showText: {
      type: Boolean
    }
  },
  data() {
    return {
      value: this.switchValue
    }
  },
  watch: {
    switchValue(val) {
      this.value = val;
    }

  },
  methods: {
    handleSwitch() {

      if (this.disabled) {
        return
      }
      this.value = !this.value
      this.$emit('change', this.value)


    }
  }
}
</script>

<style scoped lang="scss">


.switch-content {
  display: flex;
  align-items: center;
  position: relative;

  width: 50px;
  height: 26px;
  line-height: 20px;
  border-radius: 26px;
  text-align: center;
  transition: background-color 0.3s;
  border: none !important;
  border: 0 !important;
  box-shadow: 0 0 0 0.5px #e2e0e0;


  //background-color: red;
  background-color: #fff;

  &.active {
    background-color: #409eff;
    box-shadow: none !important;

  }

  &.disabled {
    opacity: 0.6 !important;
    cursor: not-allowed !important;
  }

  .loading {
    width: 8px;
    height: 8px;
    border: 1px solid #C0C4CC;
    border-radius: 50%;
    display: inline-block;
    vertical-align: middle;
    clip-path: polygon(0% 0%, 100% 0%, 100% 30%, 0% 30%);
    animation: loading 1s linear infinite;
  }

  @-webkit-keyframes loading {
    from {
      transform: rotatez(0deg);
    }

    to {
      transform: rotatez(360deg);
    }
  }

  @keyframes loading {
    from {
      transform: rotatez(0deg);
    }

    to {
      transform: rotatez(360deg);
    }
  }

}

.switch-text {
  transition: all 0.3s;
  color: #fff;
  font-size: 12px;
  position: absolute;
  left: 100%;
  transform: translateX(-120%) !important;


  &.active {
    left: 0;
    transform: translateX(50%) !important;
  }

  //color: #fff;
}

.switch-bar {
  transition: all 0.3s;

  position: absolute;
  left: 2%;
  width: 24px;
  height: 24px;
  border-radius: 24px;
  background-color: #fff;
  box-shadow: 0 3px 1px 0 rgba(0, 0, 0, 0.05), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 3px 3px 0 rgba(0, 0, 0, 0.05);

  &.active {
    left: 98% !important;
    transform: translateX(-100%) !important;

  }

}

</style>