index.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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.value) : activeValue === item.value,
  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.name }}</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. },
  51. computed: {
  52. isMultiple() {
  53. return this.mode === "multiple";
  54. }
  55. },
  56. data() {
  57. // 优先使用 echoInfo,如果 echoInfo 不为空则使用它,否则使用 defaultActive
  58. const initialValue = this.echoInfo || this.defaultActive;
  59. return {
  60. activeValue: this.isMultiple ? '' : initialValue,
  61. activeValues: this.isMultiple ? (Array.isArray(initialValue) ? initialValue : []) : []
  62. };
  63. },
  64. watch: {
  65. defaultActive: {
  66. handler(val) {
  67. // 只有当 echoInfo 为空时,才使用 defaultActive
  68. if (!this.echoInfo) {
  69. if (this.isMultiple) {
  70. this.activeValues = Array.isArray(val) ? val : [];
  71. } else {
  72. this.activeValue = val;
  73. }
  74. }
  75. },
  76. immediate: true
  77. },
  78. echoInfo: {
  79. handler(val) {
  80. if (val !== undefined && val !== null) {
  81. if (this.isMultiple) {
  82. this.activeValues = Array.isArray(val) ? val : [];
  83. } else {
  84. this.activeValue = val;
  85. }
  86. }
  87. },
  88. immediate: true
  89. },
  90. mode: {
  91. handler(newMode) {
  92. // 当 mode 变化时,重新初始化选中值
  93. const initialValue = this.echoInfo || this.defaultActive;
  94. if (newMode === 'multiple') {
  95. this.activeValues = Array.isArray(initialValue) ? initialValue : [];
  96. this.activeValue = '';
  97. } else {
  98. this.activeValue = initialValue;
  99. this.activeValues = [];
  100. }
  101. },
  102. immediate: true
  103. },
  104. isClear: {
  105. handler(val) {
  106. if (val) {
  107. this.activeValue = '';
  108. this.activeValues = [];
  109. }
  110. },
  111. immediate: true
  112. }
  113. },
  114. methods: {
  115. handleTabClick(item) {
  116. if (this.isMultiple) {
  117. this.handleMultipleSelect(item);
  118. } else {
  119. this.handleSingleSelect(item);
  120. }
  121. },
  122. handleSingleSelect(item) {
  123. this.activeValue = item.value;
  124. this.$emit("tabChange", item.value);
  125. },
  126. handleMultipleSelect(item) {
  127. const index = this.activeValues.indexOf(item.value);
  128. if (index > -1) {
  129. this.activeValues.splice(index, 1);
  130. } else {
  131. this.activeValues.push(item.value);
  132. }
  133. this.$emit("tabChange", [...this.activeValues]);
  134. }
  135. }
  136. };
  137. </script>
  138. <style lang="scss" scoped>
  139. @import "./index.scss";
  140. </style>