feat: 为DIY标签页组件添加滚动容器和样式

This commit is contained in:
2026-02-06 17:55:44 +08:00
parent 6897fc631b
commit 069b3c2c07

View File

@@ -1,14 +1,14 @@
<template> <template>
<!-- DIY 标签页组件 - 支持多种样式和位置的标签页切换 --> <!-- DIY 标签页组件 - 支持多种样式和位置的标签页切换 -->
<view data-component-name="diy-tab" class="tab-diy-component-preview-container" :class="[containerClass, styleClass]" :style="containerStyle"> <view data-component-name="diy-tab" class="tab-diy-component-preview-container"
:class="[containerClass, styleClass]" :style="containerStyle">
<!-- 顶部标签位置:标签导航 + 指示器 + 内容区域 --> <!-- 顶部标签位置:标签导航 + 指示器 + 内容区域 -->
<template v-if="mergedValue.tabPosition === 'top'"> <template v-if="mergedValue.tabPosition === 'top'">
<!-- 标签导航 --> <!-- 标签导航 -->
<view class="tab-nav" :style="tabNavStyle"> <view class="tab-nav" :style="tabNavStyle">
<view v-for="(tab, idx) in mergedValue.tabs" :key="tab.id || idx" class="tab-item" <view v-for="(tab, idx) in mergedValue.tabs" :key="tab.id || idx" class="tab-item"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" :style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" @tap="switchTab(idx)">
@tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]"> <text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]">
{{ getTabTitle(tab.title) }} {{ getTabTitle(tab.title) }}
</text> </text>
@@ -16,25 +16,26 @@
</view> </view>
<!-- 指示器 --> <!-- 指示器 -->
<view v-if="mergedValue.showIndicator" class="tab-indicator" <view v-if="mergedValue.showIndicator" class="tab-indicator" :style="{
:style="{ ...indicatorStyle,
...indicatorStyle, top: indicatorVars.top,
top: indicatorVars.top, left: indicatorVars.left,
left: indicatorVars.left, right: indicatorVars.right,
right: indicatorVars.right, bottom: indicatorVars.bottom,
bottom: indicatorVars.bottom, width: indicatorVars.width,
width: indicatorVars.width, height: indicatorVars.height
height: indicatorVars.height }"></view>
}"></view>
<!-- 内容区域 --> <!-- 内容区域 -->
<view class="tab-content" :style="contentStyle"> <view class="tab-content" :style="contentStyle">
<view v-for="(tab, idx) in mergedValue.tabs" :key="'panel' + idx" class="tab-panel" <view v-for="(tab, idx) in mergedValue.tabs" :key="'panel' + idx" class="tab-panel"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
:style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]"> :style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]">
<!-- 渲染每个标签下的组件 --> <view v-if="tab.components && tab.components.length > 0" class="tab-components">
<diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }" <!-- 渲染每个标签下的组件 -->
:scrollTop="tab.scrollTop || 0" /> <diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }"
:scrollTop="tab.scrollTop || 0" />
</view>
</view> </view>
</view> </view>
</template> </template>
@@ -46,30 +47,29 @@
<view v-for="(tab, idx) in mergedValue.tabs" :key="'panel' + idx" class="tab-panel" <view v-for="(tab, idx) in mergedValue.tabs" :key="'panel' + idx" class="tab-panel"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
:style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]"> :style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]">
<!-- 渲染每个标签下的组件 --> <view v-if="tab.components && tab.components.length > 0" class="tab-components">
<diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }" <!-- 渲染每个标签下的组件 -->
:scrollTop="tab.scrollTop || 0" /> <diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }"
:scrollTop="tab.scrollTop || 0" />
</view>
</view> </view>
</view> </view>
<!-- 指示器 --> <!-- 指示器 -->
<view v-if="mergedValue.showIndicator" class="tab-indicator" <view v-if="mergedValue.showIndicator" class="tab-indicator" :style="{
:style="{ ...indicatorStyle,
...indicatorStyle, top: indicatorVars.top,
top: indicatorVars.top, left: indicatorVars.left,
left: indicatorVars.left, right: indicatorVars.right,
right: indicatorVars.right, bottom: indicatorVars.bottom,
bottom: indicatorVars.bottom, width: indicatorVars.width,
width: indicatorVars.width, height: indicatorVars.height
height: indicatorVars.height }"></view>
}"></view>
<!-- 标签导航 --> <!-- 标签导航 -->
<view class="tab-nav" :style="tabNavStyle"> <view class="tab-nav" :style="tabNavStyle">
<view v-for="(tab, idx) in mergedValue.tabs" :key="tab.id || idx" class="tab-item" <view v-for="(tab, idx) in mergedValue.tabs" :key="tab.id || idx" class="tab-item"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" :style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" @tap="switchTab(idx)">
@tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]"> <text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]">
{{ getTabTitle(tab.title) }} {{ getTabTitle(tab.title) }}
</text> </text>
@@ -84,8 +84,7 @@
<view class="tab-nav tab-nav-vertical" :style="tabNavStyle"> <view class="tab-nav tab-nav-vertical" :style="tabNavStyle">
<view v-for="(tab, idx) in mergedValue.tabs" :key="tab.id || idx" class="tab-item tab-item-vertical" <view v-for="(tab, idx) in mergedValue.tabs" :key="tab.id || idx" class="tab-item tab-item-vertical"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" :style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" @tap="switchTab(idx)">
@tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]"> <text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]">
{{ getTabTitle(tab.title) }} {{ getTabTitle(tab.title) }}
</text> </text>
@@ -93,25 +92,26 @@
</view> </view>
<!-- 左侧指示器 --> <!-- 左侧指示器 -->
<view v-if="mergedValue.showIndicator" class="tab-indicator tab-indicator-vertical" <view v-if="mergedValue.showIndicator" class="tab-indicator tab-indicator-vertical" :style="{
:style="{ ...indicatorStyle,
...indicatorStyle, top: indicatorVars.top,
top: indicatorVars.top, left: indicatorVars.left,
left: indicatorVars.left, right: indicatorVars.right,
right: indicatorVars.right, bottom: indicatorVars.bottom,
bottom: indicatorVars.bottom, width: indicatorVars.width,
width: indicatorVars.width, height: indicatorVars.height
height: indicatorVars.height }"></view>
}"></view>
<!-- 右侧内容区域 --> <!-- 右侧内容区域 -->
<view class="tab-content" :style="contentStyle"> <view class="tab-content" :style="contentStyle">
<view v-for="(tab, idx) in mergedValue.tabs" :key="'panel' + idx" class="tab-panel" <view v-for="(tab, idx) in mergedValue.tabs" :key="'panel' + idx" class="tab-panel"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
:style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]"> :style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]">
<!-- 渲染每个标签下的组件 --> <view v-if="tab.components && tab.components.length > 0" class="tab-components">
<diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }" <!-- 渲染每个标签下的组件 -->
:scrollTop="tab.scrollTop || 0" /> <diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }"
:scrollTop="tab.scrollTop || 0" />
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -125,30 +125,30 @@
<view v-for="(tab, idx) in mergedValue.tabs" :key="'panel' + idx" class="tab-panel" <view v-for="(tab, idx) in mergedValue.tabs" :key="'panel' + idx" class="tab-panel"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
:style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]"> :style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]">
<!-- 渲染每个标签下的组件 --> <view v-if="tab.components && tab.components.length > 0" class="tab-components">
<diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }" <!-- 渲染每个标签下的组件 -->
:scrollTop="tab.scrollTop || 0" /> <diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }"
:scrollTop="tab.scrollTop || 0" />
</view>
</view> </view>
</view> </view>
<!-- 右侧指示器 --> <!-- 右侧指示器 -->
<view v-if="mergedValue.showIndicator" class="tab-indicator tab-indicator-vertical" <view v-if="mergedValue.showIndicator" class="tab-indicator tab-indicator-vertical" :style="{
:style="{ ...indicatorStyle,
...indicatorStyle, top: indicatorVars.top,
top: indicatorVars.top, left: indicatorVars.left,
left: indicatorVars.left, right: indicatorVars.right,
right: indicatorVars.right, bottom: indicatorVars.bottom,
bottom: indicatorVars.bottom, width: indicatorVars.width,
width: indicatorVars.width, height: indicatorVars.height
height: indicatorVars.height }"></view>
}"></view>
<!-- 右侧标签导航 --> <!-- 右侧标签导航 -->
<view class="tab-nav tab-nav-vertical" :style="tabNavStyle"> <view class="tab-nav tab-nav-vertical" :style="tabNavStyle">
<view v-for="(tab, idx) in mergedValue.tabs" :key="tab.id || idx" class="tab-item tab-item-vertical" <view v-for="(tab, idx) in mergedValue.tabs" :key="tab.id || idx" class="tab-item tab-item-vertical"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" :style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" @tap="switchTab(idx)">
@tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]"> <text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]">
{{ getTabTitle(tab.title) }} {{ getTabTitle(tab.title) }}
</text> </text>
@@ -1073,6 +1073,28 @@ export default {
@media (prefers-reduced-motion: reduce) { @media (prefers-reduced-motion: reduce) {
transition: none; transition: none;
} }
.tab-components {
width: 100%;
height: 100%;
overflow-y: auto;
box-sizing: border-box;
padding-right: 8px;
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.05);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(0, 0, 0, 0.3);
}
}
} }
// ===== 默认样式 ===== // ===== 默认样式 =====