refactor(tabbar): 将 tabbar 相关文件从 layouts/fg-tabbar 移动到 src/tabbar 目录
重构 tabbar 模块的文件结构,将原本位于 layouts/fg-tabbar 下的所有文件移动到 src/tabbar 目录 更新所有引用路径以匹配新的文件位置 保持原有功能不变,仅调整文件组织结构
This commit is contained in:
68
src/tabbar/fg-tabbar.vue
Normal file
68
src/tabbar/fg-tabbar.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<script setup lang="ts">
|
||||
import { tabbarStore } from './tabbar'
|
||||
// 'i-carbon-code',
|
||||
import { tabbarList as _tabBarList, cacheTabbarEnable, selectedTabbarStrategy, TABBAR_MAP } from './tabbarList'
|
||||
|
||||
const customTabbarEnable
|
||||
= selectedTabbarStrategy === TABBAR_MAP.CUSTOM_TABBAR_WITH_CACHE
|
||||
|| selectedTabbarStrategy === TABBAR_MAP.CUSTOM_TABBAR_WITHOUT_CACHE
|
||||
|
||||
/** tabbarList 里面的 path 从 pages.config.ts 得到 */
|
||||
const tabbarList = _tabBarList.map(item => ({ ...item, path: `/${item.pagePath}` }))
|
||||
function selectTabBar({ value: index }: { value: number }) {
|
||||
const url = tabbarList[index].path
|
||||
tabbarStore.setCurIdx(index)
|
||||
if (cacheTabbarEnable) {
|
||||
uni.switchTab({ url })
|
||||
}
|
||||
else {
|
||||
uni.navigateTo({ url })
|
||||
}
|
||||
}
|
||||
onLoad(() => {
|
||||
// 解决原生 tabBar 未隐藏导致有2个 tabBar 的问题
|
||||
const hideRedundantTabbarEnable = selectedTabbarStrategy === TABBAR_MAP.CUSTOM_TABBAR_WITH_CACHE
|
||||
hideRedundantTabbarEnable
|
||||
&& uni.hideTabBar({
|
||||
fail(err) {
|
||||
console.log('hideTabBar fail: ', err)
|
||||
},
|
||||
success(res) {
|
||||
console.log('hideTabBar success: ', res)
|
||||
},
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<wd-tabbar
|
||||
v-if="customTabbarEnable"
|
||||
v-model="tabbarStore.curIdx"
|
||||
bordered
|
||||
safe-area-inset-bottom
|
||||
placeholder
|
||||
fixed
|
||||
@change="selectTabBar"
|
||||
>
|
||||
<block v-for="(item, idx) in tabbarList" :key="item.path">
|
||||
<wd-tabbar-item v-if="item.iconType === 'uiLib'" :title="item.text" :icon="item.icon" />
|
||||
<wd-tabbar-item
|
||||
v-else-if="item.iconType === 'unocss' || item.iconType === 'iconfont'"
|
||||
:title="item.text"
|
||||
>
|
||||
<template #icon>
|
||||
<view
|
||||
h-40rpx
|
||||
w-40rpx
|
||||
:class="[item.icon, idx === tabbarStore.curIdx ? 'is-active' : 'is-inactive']"
|
||||
/>
|
||||
</template>
|
||||
</wd-tabbar-item>
|
||||
<wd-tabbar-item v-else-if="item.iconType === 'local'" :title="item.text">
|
||||
<template #icon>
|
||||
<image :src="item.icon" h-40rpx w-40rpx />
|
||||
</template>
|
||||
</wd-tabbar-item>
|
||||
</block>
|
||||
</wd-tabbar>
|
||||
</template>
|
||||
17
src/tabbar/tabbar.md
Normal file
17
src/tabbar/tabbar.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# tabbar 说明
|
||||
|
||||
`tabbar` 分为 `4 种` 情况:
|
||||
|
||||
- 0 `无 tabbar`,只有一个页面入口,底部无 `tabbar` 显示;常用语临时活动页。
|
||||
- 1 `原生 tabbar`,使用 `switchTab` 切换 tabbar,`tabbar` 页面有缓存。
|
||||
- 优势:原生自带的 tabbar,最先渲染,有缓存。
|
||||
- 劣势:只能使用 2 组图片来切换选中和非选中状态,修改颜色只能重新换图片(或者用 iconfont)。
|
||||
- 2 `有缓存自定义 tabbar`,使用 `switchTab` 切换 tabbar,`tabbar` 页面有缓存。使用了第三方 UI 库的 `tabbar` 组件,并隐藏了原生 `tabbar` 的显示。
|
||||
- 优势:可以随意配置自己想要的 `svg icon`,切换字体颜色方便。有缓存。可以实现各种花里胡哨的动效等。
|
||||
- 劣势:首次点击 tababr 会闪烁。
|
||||
- 3 `无缓存自定义 tabbar`,使用 `navigateTo` 切换 `tabbar`,`tabbar` 页面无缓存。使用了第三方 UI 库的 `tabbar` 组件。
|
||||
- 优势:可以随意配置自己想要的 svg icon,切换字体颜色方便。可以实现各种花里胡哨的动效等。
|
||||
- 劣势:首次点击 `tababr` 会闪烁,无缓存。
|
||||
|
||||
|
||||
> 注意:花里胡哨的效果需要自己实现,本模版不提供。
|
||||
19
src/tabbar/tabbar.ts
Normal file
19
src/tabbar/tabbar.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* tabbar 状态,增加 storageSync 保证刷新浏览器时在正确的 tabbar 页面
|
||||
* 使用reactive简单状态,而不是 pinia 全局状态
|
||||
*/
|
||||
export const tabbarStore = reactive({
|
||||
curIdx: uni.getStorageSync('app-tabbar-index') || 0,
|
||||
prevIdx: uni.getStorageSync('app-tabbar-index') || 0,
|
||||
setCurIdx(idx: number) {
|
||||
this.curIdx = idx
|
||||
uni.setStorageSync('app-tabbar-index', idx)
|
||||
},
|
||||
|
||||
restorePrevIdx() {
|
||||
if (this.prevIdx === this.curIdx)
|
||||
return
|
||||
this.setCurIdx(this.prevIdx)
|
||||
this.prevIdx = uni.getStorageSync('app-tabbar-index') || 0
|
||||
},
|
||||
})
|
||||
84
src/tabbar/tabbarList.ts
Normal file
84
src/tabbar/tabbarList.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { TabBar } from '@uni-helper/vite-plugin-uni-pages'
|
||||
|
||||
type FgTabBarItem = TabBar['list'][0] & {
|
||||
icon: string
|
||||
iconType: 'uiLib' | 'unocss' | 'iconfont'
|
||||
}
|
||||
|
||||
/**
|
||||
* tabbar 选择的策略,更详细的介绍见 tabbar.md 文件
|
||||
* 0: 'NO_TABBAR' `无 tabbar`
|
||||
* 1: 'NATIVE_TABBAR' `完全原生 tabbar`
|
||||
* 2: 'CUSTOM_TABBAR_WITH_CACHE' `有缓存自定义 tabbar`
|
||||
* 3: 'CUSTOM_TABBAR_WITHOUT_CACHE' `无缓存自定义 tabbar`
|
||||
*
|
||||
* 温馨提示:本文件的任何代码更改了之后,都需要重新运行,否则 pages.json 不会更新导致配置不生效
|
||||
*/
|
||||
export const TABBAR_MAP = {
|
||||
NO_TABBAR: 0,
|
||||
NATIVE_TABBAR: 1,
|
||||
CUSTOM_TABBAR_WITH_CACHE: 2,
|
||||
CUSTOM_TABBAR_WITHOUT_CACHE: 3,
|
||||
}
|
||||
// TODO:通过这里切换使用tabbar的策略
|
||||
export const selectedTabbarStrategy = TABBAR_MAP.CUSTOM_TABBAR_WITH_CACHE
|
||||
|
||||
// selectedTabbarStrategy==NATIVE_TABBAR(1) 时,需要填 iconPath 和 selectedIconPath
|
||||
// selectedTabbarStrategy==CUSTOM_TABBAR(2,3) 时,需要填 icon 和 iconType
|
||||
// selectedTabbarStrategy==NO_TABBAR(0) 时,tabbarList 不生效
|
||||
export const tabbarList: FgTabBarItem[] = [
|
||||
{
|
||||
iconPath: 'static/tabbar/home.png',
|
||||
selectedIconPath: 'static/tabbar/homeHL.png',
|
||||
pagePath: 'pages/index/index',
|
||||
text: '首页',
|
||||
icon: 'home',
|
||||
// 选用 UI 框架自带的 icon 时,iconType 为 uiLib
|
||||
iconType: 'uiLib',
|
||||
},
|
||||
{
|
||||
iconPath: 'static/tabbar/example.png',
|
||||
selectedIconPath: 'static/tabbar/exampleHL.png',
|
||||
pagePath: 'pages/about/about',
|
||||
text: '关于',
|
||||
icon: 'i-carbon-code',
|
||||
// 注意 unocss 图标需要如下处理:(二选一)
|
||||
// 1)在fg-tabbar.vue页面上引入一下并注释掉(见代码第三行)
|
||||
// 2)配置到 unocss.config.ts 的 safelist 中
|
||||
iconType: 'unocss',
|
||||
},
|
||||
// {
|
||||
// pagePath: 'pages/my/index',
|
||||
// text: '我的',
|
||||
// icon: '/static/logo.svg',
|
||||
// iconType: 'local',
|
||||
// },
|
||||
// {
|
||||
// pagePath: 'pages/mine/index',
|
||||
// text: '我的',
|
||||
// // 注意 iconfont 图标需要额外加上 'iconfont',如下
|
||||
// icon: 'iconfont icon-my',
|
||||
// iconType: 'iconfont',
|
||||
// },
|
||||
]
|
||||
|
||||
// NATIVE_TABBAR(1) 和 CUSTOM_TABBAR_WITH_CACHE(2) 时,需要tabbar缓存
|
||||
export const cacheTabbarEnable = selectedTabbarStrategy === TABBAR_MAP.NATIVE_TABBAR
|
||||
|| selectedTabbarStrategy === TABBAR_MAP.CUSTOM_TABBAR_WITH_CACHE
|
||||
|
||||
const _tabbar: TabBar = {
|
||||
// 只有微信小程序支持 custom。App 和 H5 不生效
|
||||
custom: selectedTabbarStrategy === TABBAR_MAP.CUSTOM_TABBAR_WITH_CACHE,
|
||||
color: '#999999',
|
||||
selectedColor: '#018d71',
|
||||
backgroundColor: '#F8F8F8',
|
||||
borderStyle: 'black',
|
||||
height: '50px',
|
||||
fontSize: '10px',
|
||||
iconWidth: '24px',
|
||||
spacing: '3px',
|
||||
list: tabbarList as unknown as TabBar['list'],
|
||||
}
|
||||
|
||||
// 0和1 需要显示底部的tabbar的各种配置,以利用缓存
|
||||
export const tabBar = cacheTabbarEnable ? _tabbar : undefined
|
||||
Reference in New Issue
Block a user