index.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <template>
  2. <view class="tab-radio-container" :style="{ gridTemplateColumns: `repeat(${colNum}, 1fr)` }">
  3. <view
  4. class="tab-item"
  5. :class="{
  6. 'tab-item--active': isMultiple ? activeValues.includes(item[valueKey]) : activeValue === item[valueKey],
  7. 'tab-item--multiple': isMultiple
  8. }"
  9. v-for="(item, index) in tabList"
  10. :key="index"
  11. @click="handleTabClick(item)"
  12. >
  13. <text class="tab-item__text">{{ item[labelKey] }}</text>
  14. <!-- <view v-if="isMultiple" class="tab-item__checkbox" :class="{ 'tab-item__checkbox--checked': activeValues.includes(item.value) }">
  15. <view v-if="activeValues.includes(item.value)" class="tab-item__checkbox-inner"></view>
  16. </view> -->
  17. </view>
  18. </view>
  19. </template>
  20. <script>
  21. export default {
  22. name: "TabRadio",
  23. props: {
  24. tabList: {
  25. type: Array,
  26. required: true,
  27. default: () => []
  28. },
  29. defaultActive: {
  30. type: [String, Number, Array],
  31. default: ""
  32. },
  33. colNum: {
  34. type: Number,
  35. default: 4
  36. },
  37. mode: {
  38. type: String,
  39. default: "single",
  40. validator: (value) => ["single", "multiple"].includes(value)
  41. },
  42. echoInfo: {
  43. type: [String, Number, Array],
  44. default: ""
  45. },
  46. isClear: {
  47. type: Boolean,
  48. default: false
  49. },
  50. valueKey: {
  51. type: String,
  52. default: "value"
  53. },
  54. labelKey: {
  55. type: String,
  56. default: "name"
  57. }
  58. },
  59. computed: {
  60. isMultiple() {
  61. return this.mode === "multiple";
  62. }
  63. },
  64. data() {
  65. // 优先使用 echoInfo,如果 echoInfo 不为空则使用它,否则使用 defaultActive
  66. const initialValue = this.echoInfo || this.defaultActive;
  67. return {
  68. activeValue: this.isMultiple ? '' : initialValue,
  69. activeValues: this.isMultiple ? (Array.isArray(initialValue) ? initialValue : []) : []
  70. };
  71. },
  72. watch: {
  73. defaultActive: {
  74. handler(val) {
  75. // 只有当 echoInfo 为空时,才使用 defaultActive
  76. if (!this.echoInfo) {
  77. if (this.isMultiple) {
  78. this.activeValues = Array.isArray(val) ? val : [];
  79. } else {
  80. this.activeValue = val;
  81. }
  82. }
  83. },
  84. immediate: true
  85. },
  86. echoInfo: {
  87. handler(val) {
  88. if (val !== undefined && val !== null) {
  89. if (this.isMultiple) {
  90. this.activeValues = Array.isArray(val) ? val : [];
  91. } else {
  92. this.activeValue = val;
  93. }
  94. }
  95. },
  96. immediate: true
  97. },
  98. mode: {
  99. handler(newMode) {
  100. // 当 mode 变化时,重新初始化选中值
  101. const initialValue = this.echoInfo || this.defaultActive;
  102. if (newMode === 'multiple') {
  103. this.activeValues = Array.isArray(initialValue) ? initialValue : [];
  104. this.activeValue = '';
  105. } else {
  106. this.activeValue = initialValue;
  107. this.activeValues = [];
  108. }
  109. },
  110. immediate: true
  111. },
  112. isClear: {
  113. handler(val) {
  114. if (val) {
  115. this.activeValue = '';
  116. this.activeValues = [];
  117. }
  118. },
  119. immediate: true
  120. }
  121. },
  122. methods: {
  123. handleTabClick(item) {
  124. if (this.isMultiple) {
  125. this.handleMultipleSelect(item);
  126. } else {
  127. this.handleSingleSelect(item);
  128. }
  129. },
  130. handleSingleSelect(item) {
  131. this.activeValue = item[this.valueKey];
  132. this.$emit("tabChange", item[this.valueKey]);
  133. },
  134. handleMultipleSelect(item) {
  135. const index = this.activeValues.indexOf(item[this.valueKey]);
  136. if (index > -1) {
  137. this.activeValues.splice(index, 1);
  138. } else {
  139. this.activeValues.push(item[this.valueKey]);
  140. }
  141. this.$emit("tabChange", [...this.activeValues]);
  142. }
  143. }
  144. };
  145. </script>
  146. <style lang="scss" scoped>
  147. @import "./index.scss";
  148. </style>