hookehuyr

feat(material-list): 重构资料列表页使用 NutTabs 替换 FilterTabs

- 移除 FilterTabs 组件依赖,改用 nut-tabs 实现自定义标签栏
- 新增测试页面 pages/test-tabs 用于验证自定义 Tabs 样式
- 调整全局样式,为 page 选择器添加 CSS 变量定义
- 更新组件类型声明,移除 NutSearchbar,添加 NutConfigProvider
- 在开发环境中注册测试页面路由
......@@ -16,19 +16,19 @@ declare module 'vue' {
NavHeader: typeof import('./src/components/NavHeader.vue')['default']
NutAvatar: typeof import('@nutui/nutui-taro')['Avatar']
NutButton: typeof import('@nutui/nutui-taro')['Button']
NutConfigProvider: typeof import('@nutui/nutui-taro')['ConfigProvider']
NutInput: typeof import('@nutui/nutui-taro')['Input']
NutPicker: typeof import('@nutui/nutui-taro')['Picker']
NutPopup: typeof import('@nutui/nutui-taro')['Popup']
NutRadio: typeof import('@nutui/nutui-taro')['Radio']
NutRadioGroup: typeof import('@nutui/nutui-taro')['RadioGroup']
NutSearchbar: typeof import('@nutui/nutui-taro')['Searchbar']
NutTabPane: typeof import('@nutui/nutui-taro')['TabPane']
NutTabs: typeof import('@nutui/nutui-taro')['Tabs']
NutUploader: typeof import('@nutui/nutui-taro')['Uploader']
OfficeViewer: typeof import('./src/components/OfficeViewer.vue')['default']
PdfPreview: typeof import('./src/components/PdfPreview.vue')['default']
Picker: typeof import('./src/components/time-picker-data/picker.vue')['default']
PlanPopup: typeof import('./src/components/PlanPopup/index.vue')['default']
PlanPopup: typeof import('./src/components/PlanSchemes/PlanPopup.vue')['default']
PosterBuilder: typeof import('./src/components/PosterBuilder/index.vue')['default']
QrCode: typeof import('./src/components/qrCode.vue')['default']
QrCodeSearch: typeof import('./src/components/qrCodeSearch.vue')['default']
......
## [2026-01-31] - 资料列表页重构与 FilterTabs 移除
### 重构
- 改造资料列表页 (`src/pages/material-list/index.vue`) 参考 `test-tabs` 实现
- 移除 `FilterTabs` 组件依赖,改用 `nut-tabs` 自定义头部实现
- 重构数据结构,从扁平列表调整为基于 Tab 的数据分布 (`tabsData`)
- 实现 `initTabsData` 函数进行数据初始化分配
- 添加 `displayTabsData` 计算属性支持跨 Tab 搜索过滤
- 增加深度样式覆盖 (`:deep`) 适配 NutUI Tabs 样式
- 添加空状态展示逻辑
---
**详细信息**
- **影响文件**: src/pages/material-list/index.vue
- **技术栈**: Vue 3, NutUI, Composition API
- **测试状态**: 已通过代码审查
- **备注**:
- 保持了原有的过滤逻辑(取余分配)
- 提升了代码的自包含性,减少了对外部组件的依赖
---
## [2026-01-31] - 优化知识库页面滚动结构
### 优化
......
......@@ -29,6 +29,7 @@ const pages = [
]
if (process.env.NODE_ENV === 'development') {
pages.push('pages/test-tabs/index')
// pages.push('pages/nfcTest/index')
// pages.push('pages/tailwindTest/index')
}
......
/*
* @Date: 2025-06-28 10:33:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2026-01-29 18:29:57
* @LastEditTime: 2026-01-31 19:52:31
* @FilePath: /manulife-weapp/src/app.js
* @Description: 应用入口文件
*/
......
......@@ -10,6 +10,8 @@
@tailwind components;
@tailwind utilities;
:root {
:root,
page {
--nut-primary-color: #007AFF;
--nut-tabs-horizontal-titles-height: 120rpx;
}
......
This diff is collapsed. Click to expand it.
/**
* Tabs 测试页面配置
*/
export default {
navigationBarTitleText: 'Tabs 测试',
enablePullDownRefresh: false,
backgroundColor: '#f5f5f5'
}
<!--
NutUI Tabs 自定义标签栏测试页面
@description 测试 NutUI Tabs 组件的自定义标签栏功能
@page pages/test-tabs
@created 2026-01-31
-->
<template>
<view class="test-tabs-page">
<view class="tabs-container">
<nut-tabs v-model="activeTab">
<!-- 自定义标签栏 - 参考 FilterTabs 样式 -->
<template #titles>
<view class="filter-tabs-wrapper">
<view
v-for="item in tabList"
:key="item.paneKey"
:class="[
'filter-tab-item',
activeTab === item.paneKey ? 'filter-tab-active' : 'filter-tab-inactive'
]"
@tap="handleTabClick(item.paneKey)"
>
<text class="filter-tab-text">{{ item.title }}</text>
</view>
</view>
</template>
<!-- Tab 内容 -->
<nut-tab-pane v-for="item in tabList" :key="item.paneKey" :pane-key="item.paneKey">
<view class="tab-content">
<text class="content-text">{{ item.content }}</text>
<view class="content-list">
<view v-for="i in 3" :key="i" class="list-item">
<text>{{ item.title }} - 列表项 {{ i }}</text>
</view>
</view>
</view>
</nut-tab-pane>
</nut-tabs>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
// 当前激活的 Tab
const activeTab = ref('c1')
// Tab 列表数据
const tabList = ref([
{
title: 'Tab 1',
paneKey: 'c1',
content: '这是 Tab 1 的内容区域'
},
{
title: 'Tab 2',
paneKey: 'c2',
content: '这是 Tab 2 的内容区域'
},
{
title: 'Tab 3',
paneKey: 'c3',
content: '这是 Tab 3 的内容区域'
},
{
title: 'Tab 4',
paneKey: 'c4',
content: '这是 Tab 4 的内容区域'
},
{
title: 'Tab 5',
paneKey: 'c5',
content: '这是 Tab 5 的内容区域'
},
{
title: 'Tab 6',
paneKey: 'c6',
content: '这是 Tab 6 的内容区域'
}
])
/**
* 处理 Tab 点击事件
* @param {string} paneKey - Tab 的 paneKey
*/
const handleTabClick = (paneKey) => {
activeTab.value = paneKey
}
</script>
<style lang="less">
.test-tabs-page {
min-height: 100vh;
background-color: #f5f5f5;
}
.page-header {
padding: 40px 30px;
background-color: #fff;
border-bottom: 1px solid #eee;
}
.page-title {
font-size: 32px;
font-weight: bold;
color: #333;
}
.tabs-container {
background-color: #fff;
margin-top: 20px;
}
// FilterTabs 风格的标签栏
.filter-tabs-wrapper {
display: flex;
overflow-x: auto;
padding: 24px 30px;
gap: 24rpx;
transition: all 0.3s ease;
// 隐藏滚动条
&::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
}
-ms-overflow-style: none;
scrollbar-width: none;
}
.filter-tab-item {
display: flex;
align-items: center;
justify-content: center;
padding: 16rpx 32rpx;
border-radius: 9999rpx;
white-space: nowrap;
transition: all 0.3s ease;
flex-shrink: 0;
}
.filter-tab-active {
background-color: #2563EB; // 蓝色背景
color: #fff;
}
.filter-tab-inactive {
background-color: #F3F4F6; // 灰色背景
color: #6B7280;
}
.filter-tab-text {
font-size: 28rpx;
font-weight: 500;
}
// Tab 内容区域
.tab-content {
padding: 30px;
min-height: 400px;
}
.content-text {
font-size: 28px;
color: #333;
margin-bottom: 30px;
display: block;
}
.content-list {
margin-top: 30px;
}
.list-item {
padding: 24px;
background-color: #f9f9f9;
border-radius: 12px;
margin-bottom: 20px;
font-size: 26px;
color: #666;
}
</style>