wd-switch.vue 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <template>
  2. <view :class="rootClass" :style="rootStyle" @click="switchValue">
  3. <view class="wd-switch__circle" :style="circleStyle"></view>
  4. </view>
  5. </template>
  6. <script lang="ts">
  7. export default {
  8. name: 'wd-switch',
  9. options: {
  10. addGlobalClass: true,
  11. virtualHost: true,
  12. styleIsolation: 'shared'
  13. }
  14. }
  15. </script>
  16. <script lang="ts" setup>
  17. import { computed, type CSSProperties, onBeforeMount } from 'vue'
  18. import { addUnit, isFunction, objToStyle } from '../common/util'
  19. import { switchProps } from './types'
  20. const props = defineProps(switchProps)
  21. const emit = defineEmits(['change', 'update:modelValue'])
  22. const rootClass = computed(() => {
  23. return `wd-switch ${props.customClass} ${props.disabled ? 'is-disabled' : ''} ${props.modelValue === props.activeValue ? 'is-checked' : ''}`
  24. })
  25. const rootStyle = computed(() => {
  26. const rootStyle: CSSProperties = {
  27. background: props.modelValue === props.activeValue ? props.activeColor : props.inactiveColor,
  28. 'border-color': props.modelValue === props.activeValue ? props.activeColor : props.inactiveColor
  29. }
  30. if (props.size) {
  31. rootStyle['font-size'] = addUnit(props.size)
  32. }
  33. return `${objToStyle(rootStyle)}${props.customStyle}`
  34. })
  35. const circleStyle = computed(() => {
  36. const circleStyle: string =
  37. (props.modelValue === props.activeValue && props.activeColor) || (props.modelValue !== props.activeValue && props.inactiveColor)
  38. ? 'box-shadow: none;'
  39. : ''
  40. return circleStyle
  41. })
  42. function switchValue() {
  43. if (props.disabled) return
  44. const newVal = props.modelValue === props.activeValue ? props.inactiveValue : props.activeValue
  45. if (props.beforeChange && isFunction(props.beforeChange)) {
  46. props.beforeChange({
  47. value: newVal,
  48. resolve: (pass: boolean) => {
  49. if (pass) {
  50. emit('update:modelValue', newVal)
  51. emit('change', {
  52. value: newVal
  53. })
  54. }
  55. }
  56. })
  57. } else {
  58. emit('update:modelValue', newVal)
  59. emit('change', {
  60. value: newVal
  61. })
  62. }
  63. }
  64. onBeforeMount(() => {
  65. if ([props.activeValue, props.inactiveValue].indexOf(props.modelValue) === -1) {
  66. emit('update:modelValue', props.inactiveValue)
  67. emit('change', {
  68. value: props.inactiveValue
  69. })
  70. }
  71. })
  72. </script>
  73. <style lang="scss" scoped>
  74. @import './index.scss';
  75. </style>