如何封装一款checkbox组件

3,232 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

TIP 👉 冤家宜解不宜结,各自回头看后头。明·冯梦龙《古今小说》

前言

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

复选框

属性

1. value 复选框是否选中
  • 值为布尔类型
2. disabled 是否可用
  • 值为布尔类型

事件

1. change 值改变事件
  • 参数:value 是否选中(值为布尔类型)

示例

<template>
  <div class="checkbox-list">
    <div class="item normal">
      <BaseCheckbox v-model="isChecked1" @change="doChange">是否会员</BaseCheckbox>
      <span>值为:{{isChecked1}}</span>
    </div>
    <div class="item normal">
      <BaseCheckbox v-model="isChecked2" @change="doChange">是否停用</BaseCheckbox>
      <span>值为:{{isChecked2}}</span>
    </div>
    <div class="item normal">
      <BaseCheckbox v-model="isChecked3" :disabled="true" @change="doChange">不可用</BaseCheckbox>
      <span>值为:{{isChecked3}}</span>
    </div>
    <div class="item normal">
      <BaseCheckbox v-model="isChecked4" :disabled="true" @change="doChange">不可用</BaseCheckbox>
      <span>值为:{{isChecked4}}</span>
    </div>
  </div>
</template>
<script>
import BaseCheckbox from '@/components/base/checkbox/index.vue'
export default {
  name: 'CheckboxDemo',
  components: {
    DetailShell,
    BaseCheckbox
  },
  data () {
    return {
      isChecked1: false,
      isChecked2: true,
      isChecked3: false,
      isChecked4: true
    }
  },
  methods: {
    doChange (val) {
      console.log('触发change事件,value = ', val)
    }
  }
}
</script>

实现checkbox.vue

<template>
  <div class="checkbox-item" @click="doSelect()">
    <input type="checkbox" :id="checkboxName" :name="checkboxName" v-model="currentValue" :disabled="disabled"/>
    <span class="item-bar">
        <span class="input-icon">
          <Icon name="tick" class="tick-icon"></Icon>
        </span>
        <span class="input-span"><slot></slot></span>
    </span>
  </div>
</template>
<script>
export default {
  name: 'BaseCheckbox',
  props: {
    // 当前是否选中
    value: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      currentValue: this.value,
      checkboxName: 'checkbox-' + Math.random().toString(36).substring(3, 6)
    }
  },
  watch: {
    value (val) {
      this.currentValue = val
    }
  },
  methods: {
    doSelect () {
      if (this.disabled) return
      this.currentValue = !this.currentValue
      this.$emit('input', this.currentValue)
      this.$emit('change', this.currentValue)
    }
  }
}
</script>
<style lang="scss" scoped px2rem="false">
$checkbox-height: $base-font-size;

.checkbox-item{
  display: inline-block;
  position: relative;
  margin-right: 20px;
  input {
    position: absolute;
    top: 50%;
    left: -100000px;
    width: 1em;
    height: 1em;
    transform: translate(0, -50%);
    font-size: inherit;
    &:checked + .item-bar {
      .input-icon {
        @include primary-background-color();
        @include primary-border-color();
        svg{
          opacity: 1;
        }
      }
    }
    &:disabled + .item-bar {
      cursor: not-allowed;
      .input-span {
        color: #999;
      }
      .input-icon{
        background-color: $bg-color-base;
      }
    }
    &:disabled:checked + .item-bar {
      .input-icon{
        background-color: $bg-color-base;
        border-color: $input-border-color;
        color: $color-text-placeholder;
      }
    }
  }
  .item-bar{
    display: inline-block;
    white-space: nowrap;
    line-height: $checkbox-height;
    cursor: pointer;
    .input-icon{
      color: #FFF;
      padding: 1px 0;
      display: inline-block;
      width: $checkbox-height;
      height: $checkbox-height;
      line-height: $checkbox-height;
      vertical-align: top;
      text-align: center;
      border: solid 1px $input-border-color;
      border-radius: 3px;
      font-size: $checkbox-height - 4px;
      svg{
        opacity: 0;
        line-height: 1;
        vertical-align: top;
      }
    }
    .input-span {
      margin-left: 10px;
      line-height: $checkbox-height;
      vertical-align: top;
      color: $color-text-regular;
    }
  }
}
</style>

「欢迎在评论区讨论」

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