fs-radio-button.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <template>
  2. <view
  3. class="fs-radio-button"
  4. :class="[
  5. selected ? checkedColorType : 'fs-radio-button-default',
  6. { 'fs-radio-button-radius': radius, 'fs-radio-button-round': round },
  7. buttonSize
  8. ]"
  9. :style="{ color: checkedColor }"
  10. @click="handleToggle"
  11. >
  12. {{ label }}
  13. <slot />
  14. </view>
  15. </template>
  16. <script>
  17. /**
  18. * 单选框组件
  19. * @description 单选框组件
  20. * @property {String} label 文本
  21. * @property {null} value 标识符(必须传)
  22. * @property {String} size = [mini | small | medium] 按钮大小
  23. * @property {String} checkedColor 选中颜色
  24. * @property {String} checkedColorType = [primary | danger | warning | info | success] 选中颜色类型
  25. */
  26. export default {
  27. name: 'fs-radio-button'
  28. }
  29. </script>
  30. <script setup>
  31. import { inject, reactive, watch, ref } from 'vue'
  32. const props = defineProps({
  33. label: String,
  34. value: {
  35. type: null,
  36. required: true
  37. },
  38. checkedColor: String,
  39. checkedColorType: String,
  40. size: {
  41. type: String,
  42. validator(value) {
  43. return ['mini', 'small', 'medium'].includes(value)
  44. }
  45. },
  46. checked: Boolean
  47. })
  48. const radioGroup = inject('radioGroup')
  49. const { radius, round } = radioGroup
  50. const checkedColorType = props.checkedColorType || radioGroup.checkedColorType
  51. const checkedColor = props.checkedColor || radioGroup.checkedColor
  52. const buttonSize = props.size || radioGroup.size
  53. let selected = ref(props.checked)
  54. watch(
  55. () => props.checked,
  56. val => {
  57. selected.value = val
  58. }
  59. )
  60. radioGroup.updateChildren({
  61. selected,
  62. value: props.value
  63. })
  64. const handleToggle = () => {
  65. radioGroup.updateValue(props.value)
  66. }
  67. </script>
  68. <style lang="scss" scoped>
  69. .fs-radio-button {
  70. padding: 10rpx 30rpx;
  71. white-space: nowrap;
  72. border: 2rpx solid currentColor;
  73. margin-right: 20rpx;
  74. margin-bottom: 20rpx;
  75. &-default {
  76. color: #999999;
  77. }
  78. &-radius {
  79. border-radius: var(--radius);
  80. }
  81. &-round {
  82. border-radius: 60rpx;
  83. }
  84. &.medium {
  85. padding: 8rpx 25rpx;
  86. font-size: 13px;
  87. }
  88. &.small {
  89. padding: 6rpx 20rpx;
  90. font-size: 12px;
  91. }
  92. &.mini {
  93. padding: 2rpx 15rpx;
  94. font-size: 11px;
  95. }
  96. }
  97. </style>