index.vue 2.24 KB
<template>
  <view
    @click="handleToggle"
    class="zui-switch"
    :class="{ 'zui-switch--disabled': disabled }"
    :style="{
      width: 2 * size + 'px',
      height: switchHeight,
      borderRadius: size + 'px',
      backgroundColor: value === activeValue ? activeColor : inactiveColor
    }"
  >
    <view
      class="zui-switch__circle"
      :style="{ width: size + 'px', height: size + 'px', transform: value === activeValue ? `translateX(${size}px)` : `translateX(0)` }"
    ></view>
  </view>
</template>

<script>
export default {
  name: 'EvanSwitch',
  props: {
    value: {
      type: [String, Number, Boolean],
      default: false
    },
    activeColor: {
      type: String,
      default: '#3296FA'
    },
    inactiveColor: {
      type: String,
      default: '#fff'
    },
    size: {
      type: Number,
      default: 22
    },
    disabled: {
      type: Boolean,
      default: false
    },
    activeValue: {
      type: [String, Number, Boolean],
      default: true
    },
    inactiveValue: {
      type: [String, Number, Boolean],
      default: false
    },
  },
  computed: {
    switchHeight() {
      // #ifdef APP-NVUE
      return this.size + 2 + 'px';
      // #endif
      // #ifndef APP-NVUE
      return this.size + 'px';
      // #endif
    }
  },
  methods: {
    handleToggle() {
      if (!this.disabled) {
        const value = this.value === this.activeValue ? this.inactiveValue : this.activeValue;
        this.$emit('input', value);
        this.$nextTick(() => {
          this.$emit('change', value);
        });
      }
    },
  }
};
</script>

<style lang="scss" scoped>
.zui-switch {
  position: relative;
  border-width: 1px;
  border-color: rgba(0, 0, 0, 0.1);
  border-style: solid;
  transition: background-color 0.3s;
  /* #ifndef APP-NVUE */
  box-sizing: content-box;
  /* #endif */
}
.zui-switch--disabled {
  opacity: 0.3;
}
.zui-switch__circle {
  position: absolute;
  left: 0;
  top: 0;
  background-color: #fff;
  border-radius: 50%;
  /* #ifndef APP-NVUE */
  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);
  /* #endif */
  /* #ifdef APP-NVUE */
  box-shadow: 1px 0 0px 0 rgba(0, 0, 0, 0.05);
  /* #endif */
  transition: transform 0.3s;
}
</style>