PaymentPeriodRadio.vue 2.65 KB
<template>
  <div>
    <!-- 标签 -->
    <div v-if="label" class="text-sm text-gray-600 mb-3 flex items-center">
      <span v-if="required" class="text-red-500 mr-1">*</span>
      <span>{{ label }}</span>
    </div>

    <!-- 单选按钮组 -->
    <div class="grid grid-cols-2 gap-3">
      <view
        v-for="option in options"
        :key="option"
        class="
          relative
          border-2
          rounded-lg
          p-4
          cursor-pointer
          transition-all
          flex
          items-center
          justify-center
          text-center
        "
        :class="
          modelValue === option
            ? 'border-primary bg-primary-light'
            : 'border-gray-300 bg-white'
        "
        @tap="selectOption(option)"
      >
        <text
          class="text-sm"
          :class="modelValue === option ? 'text-primary font-medium' : 'text-gray-500'"
        >
          {{ option }}
        </text>
      </view>
    </div>
  </div>
</template>

<script setup>
/**
 * 缴费年期单选组件
 *
 * @description 使用单选按钮组形式选择缴费年期,替代弹窗选择器
 * @component PaymentPeriodRadio
 * @example
 * <PaymentPeriodRadio
 *   v-model="paymentPeriod"
 *   label="缴费年期"
 *   :options="['整付(0-75 岁)', '5 年(0-70 岁)']"
 *   :required="true"
 * />
 */

/**
 * 组件属性
 */
const props = defineProps({
  /**
   * 标签文本
   * @type {string}
   */
  label: {
    type: String,
    default: ''
  },

  /**
   * 是否必填
   * @type {boolean}
   */
  required: {
    type: Boolean,
    default: false
  },

  /**
   * 选项数组
   * @type {Array<string>}
   * @example ['整付(0-75 岁)', '5 年(0-70 岁)', '10 年(0-70 岁)']
   */
  options: {
    type: Array,
    required: true
  },

  /**
   * 绑定的值
   * @type {string}
   */
  modelValue: {
    type: String,
    default: ''
  }
})

/**
 * 组件事件
 */
const emit = defineEmits({
  /**
   * 更新值事件
   * @event update:modelValue
   * @param {string} value - 选中的选项
   */
  'update:modelValue': (value) => typeof value === 'string'
})

/**
 * 选择选项
 * @param {string} option - 选中的选项
 */
const selectOption = (option) => {
  emit('update:modelValue', option)
}
</script>

<style lang="less">
// 主色样式 - 蓝色
.border-primary {
  border-color: #1677ff;
}

.bg-primary {
  background-color: rgba(22, 119, 255, 0.1);
}

.text-primary {
  color: #1677ff;
}

.bg-primary-light {
  background-color: rgba(22, 119, 255, 0.05);
}

.border-primary\/50 {
  border-color: rgba(22, 119, 255, 0.5);
}

// 选中状态的边框加粗
.border-primary {
  border-width: 2px;
}
</style>