index.vue 3.4 KB

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