index.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <template>
  2. <view class="form_item" :class="{ 'wrap': !inline }">
  3. <view class="form_item_key font-bold" :class="{ 'require': required }">{{ label }}</view>
  4. <view class="form_item_val">
  5. <radio-group class="input radio-group" @change="onRadioChange">
  6. <label v-for="(item, index) in options" :key="index">
  7. <radio :value="item.value" :checked="value === item.value" :disabled="readOnly" />
  8. <text>{{ item.name }}</text>
  9. </label>
  10. </radio-group>
  11. </view>
  12. </view>
  13. </template>
  14. <script setup lang="ts">
  15. import { defineProps, defineEmits, watch } from 'vue';
  16. const props = defineProps({
  17. label: {
  18. type: String,
  19. default: ''
  20. },
  21. options: {
  22. type: Array,
  23. default: () => []
  24. },
  25. inline: {
  26. type: Boolean,
  27. default: true,
  28. },
  29. readOnly: {
  30. type: Boolean,
  31. default: false
  32. },
  33. required: {
  34. type: Boolean,
  35. default: false
  36. },
  37. errorMsg: {
  38. type: String,
  39. default: '选择不合法'
  40. },
  41. value: {
  42. type: String,
  43. default: ''
  44. }
  45. });
  46. const emit = defineEmits(['radioChange', 'validateRequest', 'update:value']);
  47. const onRadioChange = (e: any) => {
  48. const val = e.detail.value;
  49. emit('radioChange', { value: val });
  50. emit('update:value', val);
  51. validateInput(val);
  52. };
  53. const validateInput = (value: string) => {
  54. emit('validateRequest', { value });
  55. };
  56. watch(() => props.value, (newVal) => {
  57. validateInput(newVal);
  58. });
  59. </script>
  60. <style>
  61. /* 表单 start */
  62. .form_item {
  63. position: relative;
  64. width: inherit;
  65. padding: 0 10upx;
  66. font-size: 30upx;
  67. height: 120upx;
  68. display: flex;
  69. align-items: center;
  70. }
  71. .form_item.wrap {
  72. flex-direction: column;
  73. align-items: stretch;
  74. justify-content: stretch;
  75. height: fit-content;
  76. }
  77. .form_item.wrap .form_item_key,
  78. .form_item.wrap .form_item_val {
  79. width: 100%;
  80. min-height: 120upx;
  81. line-height: 120upx;
  82. }
  83. .form_item + .form_item {
  84. border-top: 2upx solid #e5e5e5;
  85. }
  86. .form_item .form_item_key {
  87. padding-left: 20upx;
  88. position: relative;
  89. width: 220upx;
  90. }
  91. .form_item .form_item_val {
  92. flex: 1 0 0;
  93. text-align: right;
  94. height: inherit;
  95. padding: 0 20upx;
  96. }
  97. .form_item .form_item_val .input {
  98. height: inherit;
  99. }
  100. .form_item .form_item_val .radio-group {
  101. display: flex;
  102. align-items: center;
  103. flex-wrap: wrap;
  104. justify-content: space-between;
  105. }
  106. .img_captcha {
  107. width: 160upx;
  108. height: inherit;
  109. background-color: var(--dominantColor);
  110. color: #fff;
  111. font-weight: bold;
  112. font-size: 38upx;
  113. display: flex;
  114. align-items: center;
  115. justify-content: center;
  116. }
  117. .require::after {
  118. content: '*';
  119. position: absolute;
  120. color: #FF1D1F;
  121. top: 10%;
  122. left: 0;
  123. }
  124. /* 表单 end */
  125. .font-bold {
  126. font-weight: bold;
  127. }
  128. </style>