前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >封装一个开关组件

封装一个开关组件

作者头像
玖柒的小窝
修改2021-10-20 10:19:43
5850
修改2021-10-20 10:19:43
举报
文章被收录于专栏:各类技术文章~各类技术文章~

前言

在我们日常项目开发中,我们经常会做一些功能的开关控制,所以封装了这款开关组件。

开关组件

属性
1. value
  • 是否打开
  • 值为布尔类型
  • 默认为:false
2. disabled
  • 是否不可用
  • 值为布尔类型
  • 默认为:false
3. showText
  • 是否显示字,“开”或者“关”
  • 值为布尔类型
  • 默认为:true
事件
1. change 值改变事件
  • 参数:value 是否打开(值为布尔类型)

示例

template:

代码语言:javascript
复制
<div class="switch-list">
  <div class="item">
    <span>开启系统通知</span>
    <BaseSwitch v-model="isOpen1" @change="doChange"></BaseSwitch>
  </div>
  <div class="item">
    <span>开启短息提醒</span>
    <BaseSwitch v-model="isOpen2" @change="doChange"></BaseSwitch>
  </div>
  <div class="item">
    <span>不显示字:关</span>
    <BaseSwitch v-model="isOpen3" :showText="false" @change="doChange"></BaseSwitch>
  </div>
  <div class="item">
    <span>不显示字:开</span>
    <BaseSwitch v-model="isOpen4" :showText="false" @change="doChange"></BaseSwitch>
  </div>
  <div class="item">
    <span>不可用:关</span>
    <BaseSwitch v-model="isOpen5" :disabled="true" @change="doChange"></BaseSwitch>
  </div>
  <div class="item">
    <span>不可用:开</span>
    <BaseSwitch v-model="isOpen6" :disabled="true" @change="doChange"></BaseSwitch>
  </div>
</div>
复制代码

js:

代码语言:javascript
复制
import BaseSwitch from '@/components/base/switch/index.vue'
export default {
  name: 'SwitchDemo',
  components: {
    BaseSwitch
  },
  data () {
    return {
      isOpen1: false,
      isOpen2: true,
      isOpen3: false,
      isOpen4: true,
      isOpen5: false,
      isOpen6: true
    }
  },
  methods: {
    doChange (val) {
      console.log('触发change事件,value = ', val)
    }
  }
}
复制代码

switch.vue

代码语言:javascript
复制
<template>
  <div class="switch-bar" :class="statusClass" @click="doSwitch">
    <span v-if="showText" class="text">{{currentValue?'开':'关'}}</span><div class="switch-handle"></div>
  </div>
</template>
<script>
export default {
  name: 'BaseSwitch',
  props: {
    value: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    showText: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      currentValue: this.value
    }
  },
  computed: {
    statusClass () {
      let statusClass = []
      if (this.currentValue) {
        statusClass.push('on')
      }
      if (this.disabled) {
        statusClass.push('disabled')
      }
      if (this.currentValue && this.disabled) {
        statusClass.push('disabled-on')
      }
      return statusClass
    }
  },
  watch: {
    value (val) {
      this.currentValue = val
    }
  },
  methods: {
    doSwitch () {
      if (!this.disabled) {
        this.currentValue = !this.currentValue
        this.$emit('input', this.currentValue)
        this.$emit('change', this.currentValue)
      }
    }
  }
}
</script>
<style lang="scss" scoped px2rem="false">
$bar-width: 48px;
$bar-height: 24px;
$bar-padding: 1px;
$text-padding: 8px;
.switch-bar{
  position: relative;
  display: inline-block;
  box-sizing: border-box;
  width: $bar-width;
  height: $bar-height;
  line-height: $bar-height - 2px;
  border-radius: $bar-height / 2;
  border: 1px solid #E6E6E6;
  background-color: #BBB;
  color: #FFF;
  text-align: right;
  transition: all 0.3s ease-in-out;
  .text {
    margin: 0 $text-padding;
  }
  .switch-handle{
    position: absolute;
    left: $bar-padding;
    top: $bar-padding;
    width: $bar-height - $bar-padding * 2 - 2px;
    height: $bar-height - $bar-padding * 2 - 2px;
    border-radius: 50%;
    background-color: #FFF;
    transition: all 0.3s ease-in-out;
  }
}
.on{
  @include base-background-color();
  color: #FFF;
  text-align: left;
  .switch-handle{
    background-color: #FFF;
    transform: translateX($bar-width - $bar-height);
  }
}
.disabled {
  background-color: #E5E5E5;
  cursor: not-allowed;
  .switch-handle{
    background-color: #F2F2F2;
  }
}
.disabled-on{
  .switch-handle{
    background-color: #F9F9F9;
  }
  &:before {
    content: '';
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(255, 255, 255, .5);
    border-radius: $bar-height / 2;
  }
}

</style>
<style lang="scss" scoped>
$bar-width: 116px;
$bar-height: 60px;
$bar-padding: 4px;
$text-padding: 20px;
@media (max-width: $max-mobile-width) {
  .switch-bar{
    box-sizing: content-box;
    width: $bar-width;
    height: $bar-height;
    line-height: $bar-height;
    border-radius: $bar-height / 2;/*yes*/
    .switch-handle{
      left: $bar-padding;
      top: $bar-padding;
      width: $bar-height - $bar-padding * 2;
      height: $bar-height - $bar-padding * 2;
    }
  }
  .on{
    .switch-handle{
      transform: translateX($bar-width - $bar-height);
    }
  }
  .disabled-on:before {
    border-radius: $bar-height / 2;
  }
}
</style>
复制代码

感谢评论区大佬的点拨。

希望看完的朋友可以给个赞,鼓励一下

本文系转载,前往查看

如有侵权,请联系?cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系?cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 开关组件
    • 示例
    • switch.vue
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
    http://www.vxiaotou.com