Radio.vue 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <template>
  2. <div
  3. :class="[
  4. 'ptc-radio',
  5. { 'ptc-radio--checked': checked, 'ptc-radio--disabled': disabled },
  6. ]"
  7. @click="onClick"
  8. >
  9. <slot />
  10. </div>
  11. </template>
  12. <script setup lang="ts">
  13. import { inject, computed } from 'vue'
  14. const props = defineProps<{
  15. value: any
  16. modelValue?: any
  17. disabled?: boolean
  18. }>()
  19. const emit = defineEmits<{
  20. (e: 'update:modelValue', value: any): void
  21. (e: 'change', value: any): void
  22. }>()
  23. const parent = inject<any>('RadioGroup')
  24. const checked = computed(
  25. () => props.value === (parent ? parent.modelValue.value : props.modelValue)
  26. )
  27. function onClick() {
  28. if (checked.value) return
  29. const _emit = parent?.emit || emit
  30. _emit('update:modelValue', props.value)
  31. _emit('change', props.value)
  32. }
  33. </script>
  34. <style lang="scss">
  35. .ptc-radio {
  36. position: relative;
  37. border-radius: 8px;
  38. border: 2px solid #d9d9d9;
  39. color: #666;
  40. &--checked {
  41. border-color: $primary-color;
  42. color: $primary-color;
  43. &::after {
  44. content: '';
  45. position: absolute;
  46. right: -1px;
  47. bottom: -1px;
  48. @include icon('@img/check.png', 68px, 72px);
  49. }
  50. }
  51. &--disabled {
  52. color: #999;
  53. background: #ececec;
  54. pointer-events: none;
  55. cursor: not-allowed;
  56. }
  57. &:not(.ptc-radio--checked) [class*='icon-'] {
  58. filter: grayscale(1);
  59. opacity: 0.65;
  60. }
  61. }
  62. </style>