合同小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
4.8 KiB

  1. <template>
  2. <view class="l-radio" :class="{'l-radio--disabled': isDisabled}" :style="[styles]" @click="onClick">
  3. <slot name="radio" :checked="radioChecked" :disabled="isDisabled">
  4. <slot name="icon" :checked="radioChecked" :disabled="isDisabled">
  5. <view class="l-radio__icon" ref="iconRef"
  6. :class="['l-radio__icon--' + innerIcon, {
  7. 'l-radio__icon--checked': radioChecked,
  8. 'l-radio__icon--disabled': isDisabled
  9. }]" :style="[iconStyle]"></view>
  10. </slot>
  11. <view class="l-radio__label" :class="{'l-radio__label--disabled': isDisabled}" v-if="label || $slots['default']">
  12. <slot>{{label}}</slot>
  13. </view>
  14. </slot>
  15. </view>
  16. </template>
  17. <script lang="ts">
  18. // @ts-nocheck
  19. import { defineComponent, computed, inject, Ref , ref} from '@/uni_modules/lime-shared/vue';
  20. import { RadioValue, LRadioProps } from './type'
  21. import radioProps from './props'
  22. const name = 'l-radio'
  23. export default defineComponent({
  24. name,
  25. props: radioProps,
  26. emits: ['update:checked', 'update:modelValue', 'change', 'input'],
  27. setup(props, { emit }) {
  28. const radioGroupProps = inject<LRadioGroupComponentPublicInstance|null>('limeRadioGroupProps', null);
  29. const radioGroupValue = inject<ComputedRefImpl<any>|null>('limeRadioGroupValue', null);
  30. const radioGroupChange = inject<((value: any|null) => void)|null>('limeRadioGroupChange', null);
  31. const modelValue = ref(props.checked || props.modelValue)
  32. const innerChecked = computed({
  33. set(value: boolean){
  34. modelValue.value = value;
  35. emit('update:modelValue', value)
  36. emit('change', value)
  37. // #ifdef VUE2
  38. emit('input', value)
  39. // #endif
  40. },
  41. get(): boolean{
  42. return props.checked || props.modelValue || modelValue.value
  43. },
  44. } as WritableComputedOptions<boolean>)
  45. const isDisabled = computed(():boolean => (props.disabled || (radioGroupProps?.disabled)))
  46. const radioChecked = computed(():boolean => innerChecked.value || (props.name && props.name == radioGroupValue?.value) || (props.value && props.value == radioGroupValue?.value));
  47. const finalAllowUncheck = computed(():boolean => props.allowUncheck || (radioGroupProps?.allowUncheck));
  48. const innerIcon = computed(():string => radioGroupProps?.icon || props.icon)
  49. const innerSize = computed(():string => radioGroupProps?.size || props.size)
  50. const innerIconSize = computed(():string|null => radioGroupProps?.iconSize || props.iconSize)
  51. const innerFontSize = computed(():string|null => radioGroupProps?.fontSize || props.fontSize)
  52. const innerCheckedColor = computed(():string|null => radioGroupProps?.checkedColor || props.checkedColor)
  53. const innerIconBgColor = computed(():string => props.iconBgColor || radioGroupProps?.iconBgColor)
  54. const innerIconBorderColor = computed(():string => props.iconBorderColor || radioGroupProps?.iconBorderColor )
  55. const innerIconDisabledColor = computed(():string => props.iconDisabledColor || radioGroupProps?.iconDisabledColor)
  56. const innerIconDisabledBgColor = computed(():string => props.iconDisabledBgColor || radioGroupProps?.iconDisabledBgColor)
  57. const styles = computed(()=>{
  58. const style:Record<string, any> = {};
  59. if(radioGroupProps&& radioGroupProps.gap) {
  60. style[radioGroupProps.direction == 'horizontal' ? 'margin-right' : 'margin-bottom'] = radioGroupProps.gap!
  61. }
  62. if(innerCheckedColor.value) {
  63. style['--l-radio-icon-checked-color'] = innerCheckedColor.value!
  64. }
  65. if(innerIconBorderColor.value) {
  66. style['--l-radio-icon-border-color'] = innerIconBorderColor.value!
  67. }
  68. if(innerIconDisabledColor.value) {
  69. style['--l-radio-icon-disabled-color'] = innerIconDisabledColor.value!
  70. }
  71. if(innerIconDisabledBgColor.value) {
  72. style['--l-radio-icon-disabled-bg-color'] = innerIconDisabledBgColor.value!
  73. }
  74. if(innerFontSize.value) {
  75. style['--l-radio-font-size'] = innerFontSize.value!
  76. }
  77. if(innerIconBgColor.value) {
  78. style['--l-radio-icon-bg-color'] = innerIconBgColor.value!
  79. }
  80. return style
  81. })
  82. const iconStyle = computed(()=>{
  83. const style:Record<string, any> = {}
  84. if(innerIconSize.valuel) {
  85. style['width'] = innerIconSize.value!
  86. style['height'] = innerIconSize.value!
  87. style['--l-radio-icon-size'] = innerIconSize.value!
  88. }
  89. return style
  90. })
  91. const onClick = (e: UniPointerEvent) => {
  92. if(isDisabled.value) return;
  93. const _name = props.value || props.name
  94. if(radioGroupChange && _name) {
  95. const value = finalAllowUncheck.value && radioChecked.value ? null : _name;
  96. radioGroupChange(value);
  97. } else {
  98. const value = finalAllowUncheck.value ? !radioChecked.value : true;
  99. innerChecked.value = value
  100. }
  101. }
  102. return {
  103. styles,
  104. innerChecked,
  105. iconStyle,
  106. innerIcon,
  107. radioChecked,
  108. isDisabled,
  109. onClick,
  110. }
  111. }
  112. });
  113. </script>
  114. <style lang="scss">
  115. @import './index-u';
  116. </style>