Checkbox.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <template>
  2. <label
  3. class="checkbox"
  4. :class="{
  5. 'checked': value,
  6. 'disabled': disabled,
  7. }"
  8. @change="$event => handleChange($event)"
  9. >
  10. <span class="checkbox-input"></span>
  11. <input class="checkbox-original" type="checkbox" :checked="value">
  12. <span class="checkbox-label">
  13. <slot></slot>
  14. </span>
  15. </label>
  16. </template>
  17. <script lang="ts" setup>
  18. const props = withDefaults(defineProps<{
  19. value: boolean
  20. disabled?: boolean
  21. }>(), {
  22. disabled: false,
  23. })
  24. const emit = defineEmits<{
  25. (event: 'update:value', payload: boolean): void
  26. }>()
  27. const handleChange = (e: Event) => {
  28. if (props.disabled) return
  29. emit('update:value', (e.target as HTMLInputElement).checked)
  30. }
  31. </script>
  32. <style lang="scss" scoped>
  33. .checkbox {
  34. height: 20px;
  35. display: flex;
  36. align-items: center;
  37. cursor: pointer;
  38. &:not(.disabled).checked {
  39. .checkbox-input {
  40. background-color: $themeColor;
  41. border-color: $themeColor;
  42. }
  43. .checkbox-input::after {
  44. transform: rotate(45deg) scaleY(1);
  45. }
  46. .checkbox-label {
  47. color: $themeColor;
  48. }
  49. }
  50. &.disabled {
  51. color: #b7b7b7;
  52. cursor: default;
  53. .checkbox-input {
  54. background-color: #f5f5f5;
  55. }
  56. }
  57. }
  58. .checkbox-input {
  59. display: inline-block;
  60. position: relative;
  61. border: 1px solid #d9d9d9;
  62. border-radius: $borderRadius;
  63. width: 16px;
  64. height: 16px;
  65. background-color: #fff;
  66. vertical-align: middle;
  67. transition: border-color .15s cubic-bezier(.71, -.46, .29, 1.46), background-color .15s cubic-bezier(.71, -.46, .29, 1.46);
  68. z-index: 1;
  69. &::after {
  70. content: '';
  71. border: 2px solid #fff;
  72. border-left: 0;
  73. border-top: 0;
  74. height: 9px;
  75. left: 4px;
  76. position: absolute;
  77. top: 1px;
  78. transform: rotate(45deg) scaleY(0);
  79. width: 6px;
  80. transition: transform .15s ease-in .05s;
  81. transform-origin: center;
  82. }
  83. }
  84. .checkbox-original {
  85. opacity: 0;
  86. outline: 0;
  87. position: absolute;
  88. margin: 0;
  89. width: 0;
  90. height: 0;
  91. z-index: -1;
  92. }
  93. .checkbox-label {
  94. margin-left: 5px;
  95. line-height: 20px;
  96. font-size: 13px;
  97. user-select: none;
  98. }
  99. </style>