chore:后台页面管理编辑-平台入驻核心权益-新增Tab页,前端运行出来可以正常滑动,Tab页正常显示

This commit is contained in:
2026-09-03 16:27:30 +08:00
parent d2ad7b4108
commit cd1ba1fbe2
2 changed files with 83 additions and 39 deletions

View File

@@ -210,7 +210,7 @@ const localDevConfig = ({
// })['2724']; // 生物菌肥
// })['2811']; // 选择要使用的环境配置
// })['local-11']; // 选择要使用的环境配置
})['5g-351']; // 本地
})['2482']; // 本地
// })['local-2']; // 本地
// })['local-11']; // 本地
// })['1-test']; // test

View File

@@ -5,15 +5,18 @@
<!-- 顶部标签位置:标签导航 + 指示器 + 内容区域 -->
<template v-if="mergedValue.tabPosition === 'top'">
<!-- 标签导航 -->
<view class="tab-nav" :style="[tabNavStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getTabKey(tab, idx)" class="tab-item"
:class="{ active: activeTab === idx }"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" @tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]">
{{ getTabTitle(tab.title) }}
</text>
<scroll-view class="tab-nav" :style="[tabNavStyle]" scroll-x
:scroll-into-view="scrollIntoId" :scroll-with-animation="true">
<view class="tab-nav-inner" :style="[tabNavInnerStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getTabKey(tab, idx)" class="tab-item"
:class="{ active: activeTab === idx }" :id="getNavItemId(idx)"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}]" @tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}]">
{{ getTabTitle(tab.title) }}
</text>
</view>
</view>
</view>
</scroll-view>
<!-- 指示器 -->
<view v-if="mergedValue.showIndicator" class="tab-indicator" :style="[
@@ -74,30 +77,36 @@
]"></view>
<!-- 标签导航 -->
<view class="tab-nav" :style="[tabNavStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getTabKey(tab, idx)" class="tab-item"
:class="[{ active: activeTab === idx }, { 'hover-animation': mergedValue.animation }]"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}, tabItemHoverStyle]" @tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}, mergedValue.animation ? tabTextHoverStyle : {}]">
{{ getTabTitle(tab.title) }}
</text>
</view>
</view>
</template>
<!-- 左侧标签位置:标签导航 + 指示器 + 内容区域 (水平布局) -->
<template v-else-if="mergedValue.tabPosition === 'left'">
<view class="tab-layout-horizontal">
<!-- 左侧标签导航 -->
<view class="tab-nav tab-nav-vertical" :style="[tabNavStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getTabKey(tab, idx)" class="tab-item tab-item-vertical"
<scroll-view class="tab-nav" :style="[tabNavStyle]" scroll-x
:scroll-into-view="scrollIntoId" :scroll-with-animation="true">
<view class="tab-nav-inner" :style="[tabNavInnerStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getTabKey(tab, idx)" class="tab-item"
:class="[{ active: activeTab === idx }, { 'hover-animation': mergedValue.animation }]"
:id="getNavItemId(idx)"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}, tabItemHoverStyle]" @tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}, mergedValue.animation ? tabTextHoverStyle : {}]">
{{ getTabTitle(tab.title) }}
</text>
</view>
</view>
</scroll-view>
</template>
<!-- 左侧标签位置:标签导航 + 指示器 + 内容区域 (水平布局) -->
<template v-else-if="mergedValue.tabPosition === 'left'">
<view class="tab-layout-horizontal">
<!-- 左侧标签导航 -->
<scroll-view class="tab-nav tab-nav-vertical" :style="[tabNavStyle]" scroll-y
:scroll-into-view="scrollIntoId" :scroll-with-animation="true">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getTabKey(tab, idx)" class="tab-item tab-item-vertical"
:class="[{ active: activeTab === idx }, { 'hover-animation': mergedValue.animation }]"
:id="getNavItemId(idx)"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}, tabItemHoverStyle]" @tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}, mergedValue.animation ? tabTextHoverStyle : {}]">
{{ getTabTitle(tab.title) }}
</text>
</view>
</scroll-view>
<!-- 左侧指示器 -->
<view v-if="mergedValue.showIndicator" class="tab-indicator tab-indicator-vertical" :style="[
@@ -161,15 +170,17 @@
]"></view>
<!-- 右侧标签导航 -->
<view class="tab-nav tab-nav-vertical" :style="[tabNavStyle]">
<scroll-view class="tab-nav tab-nav-vertical" :style="[tabNavStyle]" scroll-y
:scroll-into-view="scrollIntoId" :scroll-with-animation="true">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getTabKey(tab, idx)" class="tab-item tab-item-vertical"
:class="[{ active: activeTab === idx }, { 'hover-animation': mergedValue.animation }]"
:id="getNavItemId(idx)"
:style="[tabItemStyle, activeTab === idx ? tabItemActiveStyle : {}, tabItemHoverStyle]" @tap="switchTab(idx)">
<text class="tab-text" :style="[tabTextStyle, activeTab === idx ? tabTextActiveStyle : {}, mergedValue.animation ? tabTextHoverStyle : {}]">
{{ getTabTitle(tab.title) }}
</text>
</view>
</view>
</scroll-view>
</view>
</template>
</view>
@@ -208,6 +219,7 @@ export default {
data() {
return {
activeTab: this.value?.activeTabIndex ?? 0, // 设置当前激活的标签索引
scrollIntoId: '', // scroll-view 滚动定位的导航项 id
indicatorVars: { // 指示器CSS变量
top: '',
left: '',
@@ -229,6 +241,8 @@ export default {
// 初始化指示器位置
this.$nextTick(() => {
this.updateIndicatorPosition();
// 初始化时将激活标签滚动到可视区域
this.syncScrollIntoId();
});
},
@@ -417,14 +431,6 @@ export default {
// 对于水平布局(顶部和底部),设置固定高度
if (this.mergedValue.tabPosition === 'top' || this.mergedValue.tabPosition === 'bottom') {
style.height = this.formatStyleValue(this.mergedValue.tabHeight, 24);
// 应用对齐方式
if (this.mergedValue.navAlign === 'start') {
style.justifyContent = 'flex-start';
} else if (this.mergedValue.navAlign === 'center') {
style.justifyContent = 'center';
} else if (this.mergedValue.navAlign === 'end') {
style.justifyContent = 'flex-end';
}
}
// 对于垂直布局(左侧和右侧),不设置固定高度,让它自适应内容
else {
@@ -451,6 +457,24 @@ export default {
return style;
},
// 导航栏内层容器样式(与后端版本一致)
tabNavInnerStyle() {
let style = {};
// 仅水平布局(顶部和底部)应用对齐方式
if (this.mergedValue.tabPosition === 'top' || this.mergedValue.tabPosition === 'bottom') {
if (this.mergedValue.navAlign === 'start') {
style.justifyContent = 'flex-start';
} else if (this.mergedValue.navAlign === 'center') {
style.justifyContent = 'center';
} else if (this.mergedValue.navAlign === 'end') {
style.justifyContent = 'flex-end';
}
}
return style;
},
// 标签项样式(与后端版本一致)
tabItemStyle() {
let style = {
@@ -601,9 +625,10 @@ export default {
// 监听器
watch: {
// 监听激活标签变化,更新指示器
// 监听激活标签变化,更新指示器并滚动导航
activeTab: {
handler() {
this.syncScrollIntoId();
this.$nextTick(() => {
this.updateIndicatorPosition();
});
@@ -724,6 +749,16 @@ export default {
getTabKey(tab, idx) {
return `tab-${tab?.id ?? idx}`;
},
// 获取导航项的 DOM id(用于 scroll-view 的 scroll-into-view 定位)
getNavItemId(idx) {
return `tab-nav-item-${idx}`;
},
// 将当前激活标签滚动到导航栏可视区域
syncScrollIntoId() {
this.$nextTick(() => {
this.scrollIntoId = this.getNavItemId(this.activeTab);
});
},
// 更新指示器位置(与后端版本一致)
updateIndicatorPosition() {
this.$nextTick(() => {
@@ -1034,8 +1069,6 @@ export default {
// ===== 标签导航栏样式 =====
.tab-nav {
display: flex;
align-items: center;
padding: 5px 0;
border-bottom: 1px solid #e0e0e0;
overflow-x: auto;
@@ -1049,6 +1082,16 @@ export default {
}
}
// 导航栏内层容器:使用 inline-flex 让内容自然撑开宽度,保证小程序 scroll-view 可横向滚动
.tab-nav-inner {
display: inline-flex;
align-items: center;
width: max-content;
min-width: 100%;
height: 100%;
box-sizing: border-box;
}
// 垂直导航栏
.tab-nav-vertical {
flex-direction: column;
@@ -1068,6 +1111,7 @@ export default {
justify-content: center;
height: 100%;
user-select: none;
flex-shrink: 0; // 防止标签在 scroll-view 内被压缩,保证可完整展示并横向滑动
&.active {
color: var(--active-color, #339af0);