cwg-asset-tabs.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. <template>
  2. <view class="asset-tabs">
  3. <!-- PC/平板 标签栏 -->
  4. <view class="tab-list">
  5. <view v-for="tab in tabs" :key="tab.value" class="tab-item" :class="{ active: currentValue === tab.value }"
  6. @click="handleClick(tab.value)">
  7. <text class="tab-label">{{ tab.text }}</text>
  8. </view>
  9. </view>
  10. <!-- 移动端 下拉选择器 -->
  11. <cwg-combox v-model:value="currentValue" :clearable="false" :options="tabs" :placeholder="t('placeholder.choose')"
  12. class="tab-picker" />
  13. </view>
  14. </template>
  15. <script setup>
  16. import { ref, watch } from 'vue'
  17. import { useI18n } from 'vue-i18n'
  18. const { t } = useI18n()
  19. // Props 定义
  20. const props = defineProps({
  21. tabs: {
  22. type: Array,
  23. required: true
  24. },
  25. // v-model 绑定的值
  26. modelValue: {
  27. type: [String, Number],
  28. required: true
  29. }
  30. })
  31. // Emits 定义
  32. const emit = defineEmits(['update:modelValue'])
  33. // 内部状态,同步 props.modelValue
  34. const currentValue = ref(props.modelValue)
  35. // 监听 props.modelValue 变化,更新内部状态
  36. watch(() => props.modelValue, (newVal) => {
  37. if (newVal !== currentValue.value) {
  38. currentValue.value = newVal
  39. }
  40. })
  41. // 监听内部状态变化,触发 update:modelValue 事件
  42. watch(currentValue, (newVal) => {
  43. emit('update:modelValue', newVal)
  44. })
  45. // 点击标签切换
  46. const handleClick = (value) => {
  47. if (value === currentValue.value) return
  48. currentValue.value = value
  49. }
  50. </script>
  51. <style lang="scss" scoped>
  52. @import "@/uni.scss";
  53. .asset-tabs {
  54. position: relative;
  55. width: 100%;
  56. margin-bottom: px2rpx(24);
  57. background-color: #fff;
  58. }
  59. .tab-list {
  60. display: flex;
  61. gap: px2rpx(20);
  62. margin: 0;
  63. padding: 0;
  64. border-bottom: 1px solid #e5e5e5;
  65. }
  66. .tab-item {
  67. text-align: center;
  68. cursor: pointer;
  69. padding: px2rpx(12) 0;
  70. }
  71. .tab-label {
  72. font-size: px2rpx(14);
  73. color: var(--bs-heading-color);
  74. transition: all 0.3s;
  75. }
  76. .tab-item.active .tab-label {
  77. color: var(--color-primary);
  78. font-weight: 500;
  79. border-bottom: 2px solid var(--color-primary);
  80. padding-bottom: px2rpx(10);
  81. }
  82. .tab-picker {
  83. display: none;
  84. width: 100%;
  85. box-sizing: border-box;
  86. }
  87. @media (max-width: 768px) {
  88. .tab-list {
  89. display: none;
  90. }
  91. .tab-picker {
  92. display: block;
  93. }
  94. }
  95. </style>