提交 5f11b43b 编写于 作者: D DCloud_LXH

feat: support dynamic tabbarItem hidden

上级 6cb65c85
......@@ -255,6 +255,7 @@ declare namespace UniApp {
selectedIconPath?: string
redDot?: boolean
badge?: string
visible?: boolean
}
interface TabBarNormalItemOptions extends TabBarItemBaseOptions {
......
......@@ -10,79 +10,79 @@ const __uniRoutes = instanceContext.__uniRoutes;
var serviceContext = (function (vue) {
'use strict';
/*
* base64-arraybuffer
* https://github.com/niklasvh/base64-arraybuffer
*
* Copyright (c) 2012 Niklas von Hertzen
* Licensed under the MIT license.
*/
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Use a lookup table to find the index.
var lookup = /*#__PURE__*/ (function () {
const lookup = new Uint8Array(256);
for (var i = 0; i < chars.length; i++) {
lookup[chars.charCodeAt(i)] = i;
}
return lookup
})();
function encode$3(arraybuffer) {
var bytes = new Uint8Array(arraybuffer),
i,
len = bytes.length,
base64 = '';
for (i = 0; i < len; i += 3) {
base64 += chars[bytes[i] >> 2];
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
base64 += chars[bytes[i + 2] & 63];
}
if (len % 3 === 2) {
base64 = base64.substring(0, base64.length - 1) + '=';
} else if (len % 3 === 1) {
base64 = base64.substring(0, base64.length - 2) + '==';
}
return base64
}
function decode$1(base64) {
var bufferLength = base64.length * 0.75,
len = base64.length,
i,
p = 0,
encoded1,
encoded2,
encoded3,
encoded4;
if (base64[base64.length - 1] === '=') {
bufferLength--;
if (base64[base64.length - 2] === '=') {
bufferLength--;
}
}
var arraybuffer = new ArrayBuffer(bufferLength),
bytes = new Uint8Array(arraybuffer);
for (i = 0; i < len; i += 4) {
encoded1 = lookup[base64.charCodeAt(i)];
encoded2 = lookup[base64.charCodeAt(i + 1)];
encoded3 = lookup[base64.charCodeAt(i + 2)];
encoded4 = lookup[base64.charCodeAt(i + 3)];
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
}
return arraybuffer
/*
* base64-arraybuffer
* https://github.com/niklasvh/base64-arraybuffer
*
* Copyright (c) 2012 Niklas von Hertzen
* Licensed under the MIT license.
*/
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Use a lookup table to find the index.
var lookup = /*#__PURE__*/ (function () {
const lookup = new Uint8Array(256);
for (var i = 0; i < chars.length; i++) {
lookup[chars.charCodeAt(i)] = i;
}
return lookup
})();
function encode$3(arraybuffer) {
var bytes = new Uint8Array(arraybuffer),
i,
len = bytes.length,
base64 = '';
for (i = 0; i < len; i += 3) {
base64 += chars[bytes[i] >> 2];
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
base64 += chars[bytes[i + 2] & 63];
}
if (len % 3 === 2) {
base64 = base64.substring(0, base64.length - 1) + '=';
} else if (len % 3 === 1) {
base64 = base64.substring(0, base64.length - 2) + '==';
}
return base64
}
function decode$1(base64) {
var bufferLength = base64.length * 0.75,
len = base64.length,
i,
p = 0,
encoded1,
encoded2,
encoded3,
encoded4;
if (base64[base64.length - 1] === '=') {
bufferLength--;
if (base64[base64.length - 2] === '=') {
bufferLength--;
}
}
var arraybuffer = new ArrayBuffer(bufferLength),
bytes = new Uint8Array(arraybuffer);
for (i = 0; i < len; i += 4) {
encoded1 = lookup[base64.charCodeAt(i)];
encoded2 = lookup[base64.charCodeAt(i + 1)];
encoded3 = lookup[base64.charCodeAt(i + 2)];
encoded4 = lookup[base64.charCodeAt(i + 3)];
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
}
return arraybuffer
}
/**
......@@ -6163,7 +6163,7 @@ var serviceContext = (function (vue) {
/**
* 动态设置 tabBar 某一项的内容
*/
function setTabBarItem$1(index, text, iconPath, selectedIconPath) {
function setTabBarItem$1(index, text, iconPath, selectedIconPath, visible) {
const item = {
index,
};
......@@ -6176,7 +6176,18 @@ var serviceContext = (function (vue) {
if (selectedIconPath) {
item.selectedIconPath = getRealPath(selectedIconPath);
}
tabBar && tabBar.setTabBarItem(item);
if (visible !== undefined) {
item.visible = config.list[index].visible = visible;
delete item.index;
const tabbarItems = config.list.map((item) => ({
visible: item.visible,
}));
tabbarItems[index] = item;
tabBar && tabBar.setTabBarItems({ list: tabbarItems });
}
else {
tabBar && tabBar.setTabBarItem(item);
}
}
/**
* 动态设置 tabBar 的整体样式
......@@ -9301,8 +9312,8 @@ var serviceContext = (function (vue) {
tabBar$1.setTabBarBadge('text', index, text);
resolve();
}, SetTabBarBadgeProtocol, SetTabBarBadgeOptions);
const setTabBarItem = defineAsyncApi(API_SET_TAB_BAR_ITEM, ({ index, text, iconPath, selectedIconPath, pagePath }, { resolve, reject }) => {
tabBar$1.setTabBarItem(index, text, iconPath, selectedIconPath);
const setTabBarItem = defineAsyncApi(API_SET_TAB_BAR_ITEM, ({ index, text, iconPath, selectedIconPath, pagePath, visible }, { resolve, reject }) => {
tabBar$1.setTabBarItem(index, text, iconPath, selectedIconPath, visible);
const route = pagePath && __uniRoutes.find(({ path }) => path === pagePath);
if (route) {
const meta = route.meta;
......
......@@ -47,10 +47,10 @@ export const setTabBarBadge = defineAsyncApi<API_TYPE_SET_TAB_BAR_BADGE>(
export const setTabBarItem = defineAsyncApi<API_TYPE_SET_TAB_BAR_ITEM>(
API_SET_TAB_BAR_ITEM,
(
{ index, text, iconPath, selectedIconPath, pagePath },
{ index, text, iconPath, selectedIconPath, pagePath, visible },
{ resolve, reject }
) => {
tabBar.setTabBarItem(index, text, iconPath, selectedIconPath)
tabBar.setTabBarItem(index, text, iconPath, selectedIconPath, visible)
const route = pagePath && __uniRoutes.find(({ path }) => path === pagePath)
if (route) {
const meta = route.meta
......
......@@ -52,9 +52,11 @@ function setTabBarItem(
index: number,
text?: string,
iconPath?: string,
selectedIconPath?: string
selectedIconPath?: string,
visible?: boolean
) {
const item: Record<string, string | number> = {
type TabBarItem = Record<string, string | number | boolean | undefined>
const item: TabBarItem = {
index,
}
if (text !== undefined) {
......@@ -66,7 +68,19 @@ function setTabBarItem(
if (selectedIconPath) {
item.selectedIconPath = getRealPath(selectedIconPath)
}
tabBar && tabBar.setTabBarItem(item)
if (visible !== undefined) {
item.visible = config.list[index].visible = visible
delete item.index
const tabbarItems = config.list.map<TabBarItem>((item) => ({
visible: item.visible,
}))
tabbarItems[index] = item
tabBar && tabBar.setTabBarItems({ list: tabbarItems })
} else {
tabBar && tabBar.setTabBarItem(item)
}
}
/**
* 动态设置 tabBar 的整体样式
......
......@@ -54,7 +54,7 @@ export function normalizePagesJson(jsonStr: string, platform: UniApp.PLATFORM) {
)
// tabBar
if (pagesJson.tabBar) {
const tabBar = normalizeTabBar(pagesJson.tabBar!)
const tabBar = normalizeTabBar(pagesJson.tabBar!, platform)
if (tabBar) {
pagesJson.tabBar = tabBar
} else {
......@@ -289,29 +289,34 @@ const DEFAULT_TAB_BAR: Partial<UniApp.TabBarOptions> = {
height: TABBAR_HEIGHT + 'px',
}
function normalizeTabBar(tabBar: UniApp.TabBarOptions) {
function normalizeTabBar(
tabBar: UniApp.TabBarOptions,
platform: UniApp.PLATFORM
) {
const { list, midButton } = tabBar
if (!list || !list.length) {
return
}
tabBar = extend({}, DEFAULT_TAB_BAR, tabBar)
const len = list.length
if (len % 2 === 0 && isPlainObject(midButton)) {
list.splice(
Math.floor(len / 2),
0,
extend(
{
type: 'midButton',
width: '50px',
height: '50px',
iconWidth: '24px',
},
midButton
if (platform === 'h5') {
const len = list.length
if (len % 2 === 0 && isPlainObject(midButton)) {
list.splice(
Math.floor(len / 2),
0,
extend(
{
type: 'midButton',
width: '50px',
height: '50px',
iconWidth: '24px',
},
midButton
)
)
)
} else {
delete tabBar.midButton
} else {
delete tabBar.midButton
}
}
list.forEach((item) => {
if (item.iconPath) {
......
......@@ -9744,16 +9744,18 @@ const UniServiceJSBridge$1 = /* @__PURE__ */ shared.extend(ServiceJSBridge, {
var TabBar = /* @__PURE__ */ defineSystemComponent({
name: "TabBar",
setup() {
const visibleList = vue.ref([]);
const tabBar2 = useTabBar();
useVisibleList(tabBar2, visibleList);
useTabBarCssVar(tabBar2);
const onSwitchTab = useSwitchTab(vueRouter.useRoute(), tabBar2);
const onSwitchTab = useSwitchTab(vueRouter.useRoute(), tabBar2, visibleList);
const {
style,
borderStyle,
placeholderStyle
} = useTabBarStyle(tabBar2);
return () => {
const tabBarItemsTsx = createTabBarItemsTsx(tabBar2, onSwitchTab);
const tabBarItemsTsx = createTabBarItemsTsx(tabBar2, onSwitchTab, visibleList);
return vue.createVNode("uni-tabbar", {
"class": "uni-tabbar-" + tabBar2.position
}, [vue.createVNode("div", {
......@@ -9776,15 +9778,26 @@ function useTabBarCssVar(tabBar2) {
});
});
}
function useSwitchTab(route, tabBar2) {
function useVisibleList(tabBar2, visibleList) {
function setVisibleList() {
let tempList = [];
tempList = tabBar2.list.filter((item) => item.visible !== false);
if (__UNI_FEATURE_TABBAR_MIDBUTTON__) {
tempList = tempList.filter((item) => !isMidButton(item));
if (tempList.length % 2 === 0) {
tempList.splice(Math.floor(tempList.length / 2), 0, tabBar2.list[Math.floor(tabBar2.list.length / 2)]);
}
}
visibleList.value = tempList;
}
vue.watchEffect(setVisibleList);
}
function useSwitchTab(route, tabBar2, visibleList) {
vue.watchEffect(() => {
const meta = route.meta;
if (meta.isTabBar) {
const pagePath = meta.route;
const index2 = tabBar2.list.findIndex((item) => item.pagePath === pagePath);
if (index2 === -1) {
return;
}
const index2 = visibleList.value.findIndex((item) => item.pagePath === pagePath);
tabBar2.selectedIndex = index2;
}
});
......@@ -9867,14 +9880,13 @@ function useTabBarStyle(tabBar2) {
function isMidButton(item) {
return item.type === "midButton";
}
function createTabBarItemsTsx(tabBar2, onSwitchTab) {
function createTabBarItemsTsx(tabBar2, onSwitchTab, visibleList) {
const {
list,
selectedIndex,
selectedColor,
color
} = tabBar2;
return list.map((item, index2) => {
return visibleList.value.map((item, index2) => {
const selected = selectedIndex === index2;
const textColor = selected ? selectedColor : color;
const iconPath = (selected ? item.selectedIconPath || item.iconPath : item.iconPath) || "";
......@@ -9958,7 +9970,7 @@ function createTabBarMidButtonTsx(color, iconPath, midButton, tabBar2, index2, o
iconWidth
} = midButton;
return vue.createVNode("div", {
"key": index2,
"key": "midButton",
"class": "uni-tabbar__item",
"style": {
flex: "0 0 " + width,
......
......@@ -18549,7 +18549,7 @@ const stopPullDownRefresh = /* @__PURE__ */ defineAsyncApi(API_STOP_PULL_DOWN_RE
UniServiceJSBridge.invokeViewMethod(API_STOP_PULL_DOWN_REFRESH, {}, getCurrentPageId());
resolve();
});
const setTabBarItemProps = ["text", "iconPath", "selectedIconPath"];
const setTabBarItemProps = ["text", "iconPath", "selectedIconPath", "visible"];
const setTabBarStyleProps = [
"color",
"selectedColor",
......@@ -18629,10 +18629,10 @@ const setTabBarStyle = /* @__PURE__ */ defineAsyncApi(API_SET_TAB_BAR_STYLE, (ar
setTabBar(API_SET_TAB_BAR_STYLE, args, resolve);
}, SetTabBarStyleProtocol, SetTabBarStyleOptions);
const hideTabBar = /* @__PURE__ */ defineAsyncApi(API_HIDE_TAB_BAR, (args, { resolve }) => {
setTabBar(API_HIDE_TAB_BAR, args, resolve);
setTabBar(API_HIDE_TAB_BAR, args ? args : {}, resolve);
}, HideTabBarProtocol);
const showTabBar = /* @__PURE__ */ defineAsyncApi(API_SHOW_TAB_BAR, (args, { resolve }) => {
setTabBar(API_SHOW_TAB_BAR, args, resolve);
setTabBar(API_SHOW_TAB_BAR, args ? args : {}, resolve);
}, ShowTabBarProtocol);
const hideTabBarRedDot = /* @__PURE__ */ defineAsyncApi(API_HIDE_TAB_BAR_RED_DOT, (args, { resolve }) => {
setTabBar(API_HIDE_TAB_BAR_RED_DOT, args, resolve);
......@@ -18649,16 +18649,18 @@ const setTabBarBadge = /* @__PURE__ */ defineAsyncApi(API_SET_TAB_BAR_BADGE, (ar
var TabBar = /* @__PURE__ */ defineSystemComponent({
name: "TabBar",
setup() {
const visibleList = ref([]);
const tabBar2 = useTabBar();
useVisibleList(tabBar2, visibleList);
useTabBarCssVar(tabBar2);
const onSwitchTab = useSwitchTab(useRoute(), tabBar2);
const onSwitchTab = useSwitchTab(useRoute(), tabBar2, visibleList);
const {
style,
borderStyle,
placeholderStyle
} = useTabBarStyle(tabBar2);
return () => {
const tabBarItemsTsx = createTabBarItemsTsx(tabBar2, onSwitchTab);
const tabBarItemsTsx = createTabBarItemsTsx(tabBar2, onSwitchTab, visibleList);
return createVNode("uni-tabbar", {
"class": "uni-tabbar-" + tabBar2.position
}, [createVNode("div", {
......@@ -18681,15 +18683,26 @@ function useTabBarCssVar(tabBar2) {
});
});
}
function useSwitchTab(route, tabBar2) {
function useVisibleList(tabBar2, visibleList) {
function setVisibleList() {
let tempList = [];
tempList = tabBar2.list.filter((item) => item.visible !== false);
if (__UNI_FEATURE_TABBAR_MIDBUTTON__) {
tempList = tempList.filter((item) => !isMidButton(item));
if (tempList.length % 2 === 0) {
tempList.splice(Math.floor(tempList.length / 2), 0, tabBar2.list[Math.floor(tabBar2.list.length / 2)]);
}
}
visibleList.value = tempList;
}
watchEffect(setVisibleList);
}
function useSwitchTab(route, tabBar2, visibleList) {
watchEffect(() => {
const meta = route.meta;
if (meta.isTabBar) {
const pagePath = meta.route;
const index2 = tabBar2.list.findIndex((item) => item.pagePath === pagePath);
if (index2 === -1) {
return;
}
const index2 = visibleList.value.findIndex((item) => item.pagePath === pagePath);
tabBar2.selectedIndex = index2;
}
});
......@@ -18772,14 +18785,13 @@ function useTabBarStyle(tabBar2) {
function isMidButton(item) {
return item.type === "midButton";
}
function createTabBarItemsTsx(tabBar2, onSwitchTab) {
function createTabBarItemsTsx(tabBar2, onSwitchTab, visibleList) {
const {
list: list2,
selectedIndex,
selectedColor,
color
} = tabBar2;
return list2.map((item, index2) => {
return visibleList.value.map((item, index2) => {
const selected = selectedIndex === index2;
const textColor = selected ? selectedColor : color;
const iconPath = (selected ? item.selectedIconPath || item.iconPath : item.iconPath) || "";
......@@ -18863,7 +18875,7 @@ function createTabBarMidButtonTsx(color, iconPath, midButton, tabBar2, index2, o
iconWidth
} = midButton;
return createVNode("div", {
"key": index2,
"key": "midButton",
"class": "uni-tabbar__item",
"style": {
flex: "0 0 " + width,
......
import { watch, watchEffect, computed } from 'vue'
import { watch, watchEffect, computed, ref, Ref } from 'vue'
import { RouteLocationNormalizedLoaded, useRoute } from 'vue-router'
import { invokeHook, updatePageCssVar } from '@dcloudio/uni-core'
import {
......@@ -14,12 +14,18 @@ import { normalizeWindowBottom } from '../../../helpers/cssVar'
export default /*#__PURE__*/ defineSystemComponent({
name: 'TabBar',
setup() {
const visibleList = ref<UniApp.TabBarItemOptions[]>([])
const tabBar = useTabBar()!
useVisibleList(tabBar, visibleList)
useTabBarCssVar(tabBar)
const onSwitchTab = useSwitchTab(useRoute(), tabBar)
const onSwitchTab = useSwitchTab(useRoute(), tabBar, visibleList)
const { style, borderStyle, placeholderStyle } = useTabBarStyle(tabBar)
return () => {
const tabBarItemsTsx = createTabBarItemsTsx(tabBar, onSwitchTab)
const tabBarItemsTsx = createTabBarItemsTsx(
tabBar,
onSwitchTab,
visibleList
)
return (
<uni-tabbar class={'uni-tabbar-' + tabBar.position}>
<div class="uni-tabbar" style={style.value}>
......@@ -46,18 +52,44 @@ function useTabBarCssVar(tabBar: UniApp.TabBarOptions) {
)
}
function useVisibleList(
tabBar: UniApp.TabBarOptions,
visibleList: Ref<UniApp.TabBarItemOptions[]>
) {
function setVisibleList() {
let tempList = []
tempList = tabBar.list.filter((item) => item.visible !== false)
if (__UNI_FEATURE_TABBAR_MIDBUTTON__) {
tempList = tempList.filter((item) => !isMidButton(item))
if (tempList.length % 2 === 0) {
tempList.splice(
Math.floor(tempList.length / 2),
0,
tabBar.list[Math.floor(tabBar.list.length / 2)]
)
}
}
visibleList.value = tempList
}
watchEffect(setVisibleList)
}
function useSwitchTab(
route: RouteLocationNormalizedLoaded,
tabBar: UniApp.TabBarOptions
tabBar: UniApp.TabBarOptions,
visibleList: Ref<UniApp.TabBarItemOptions[]>
) {
watchEffect(() => {
const meta = route.meta
if (meta.isTabBar) {
const pagePath = meta.route
const index = tabBar.list.findIndex((item) => item.pagePath === pagePath)
if (index === -1) {
return
}
const index = visibleList.value.findIndex(
(item) => item.pagePath === pagePath
)
tabBar.selectedIndex = index
}
})
......@@ -141,10 +173,11 @@ function isMidButton(item: unknown): item is UniApp.TabBarMidButtonOptions {
function createTabBarItemsTsx(
tabBar: UniApp.TabBarOptions,
onSwitchTab: OnSwtichTab
onSwitchTab: OnSwtichTab,
visibleList: Ref<UniApp.TabBarItemOptions[]>
) {
const { list, selectedIndex, selectedColor, color } = tabBar
return list.map((item, index) => {
const { selectedIndex, selectedColor, color } = tabBar
return visibleList.value.map((item, index) => {
const selected = selectedIndex === index
const textColor = selected ? selectedColor : color
const iconPath =
......@@ -267,7 +300,7 @@ function createTabBarMidButtonTsx(
const { width, height, backgroundImage, iconWidth } = midButton
return (
<div
key={index}
key="midButton"
class="uni-tabbar__item"
style={{ flex: '0 0 ' + width, position: 'relative' }}
onClick={onSwitchTab(midButton, index)}
......
......@@ -34,7 +34,7 @@ import {
} from '@dcloudio/uni-api'
import { useTabBar } from '../../../framework/setup/state'
import { getRouteOptions } from '@dcloudio/uni-core'
const setTabBarItemProps = ['text', 'iconPath', 'selectedIconPath']
const setTabBarItemProps = ['text', 'iconPath', 'selectedIconPath', 'visible']
const setTabBarStyleProps = [
'color',
'selectedColor',
......@@ -144,7 +144,7 @@ export const setTabBarStyle = defineAsyncApi<API_TYPE_SET_TAB_BAR_STYLE>(
export const hideTabBar = defineAsyncApi<API_TYPE_HIDE_TAB_BAR>(
API_HIDE_TAB_BAR,
(args, { resolve }) => {
setTabBar(API_HIDE_TAB_BAR, args, resolve)
setTabBar(API_HIDE_TAB_BAR, args ? args : {}, resolve)
},
HideTabBarProtocol
)
......@@ -152,7 +152,7 @@ export const hideTabBar = defineAsyncApi<API_TYPE_HIDE_TAB_BAR>(
export const showTabBar = defineAsyncApi<API_TYPE_SHOW_TAB_BAR>(
API_SHOW_TAB_BAR,
(args, { resolve }) => {
setTabBar(API_SHOW_TAB_BAR, args, resolve)
setTabBar(API_SHOW_TAB_BAR, args ? args : {}, resolve)
},
ShowTabBarProtocol
)
......
......@@ -922,10 +922,10 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@dcloudio/types@2.5.8":
version "2.5.8"
resolved "https://registry.yarnpkg.com/@dcloudio/types/-/types-2.5.8.tgz#3aee4b179bb4c13877309dc0fe1ba4ca1ff7d3b0"
integrity sha512-H/6I+Ui2F/g/juepMrx3wx2jfOFI8sRlKlAxOMycR2o75/ghVIhJU6GW9hU1DYNActGsM5UhcdpZYLL0qXkr4Q==
"@dcloudio/types@2.5.9":
version "2.5.9"
resolved "https://registry.yarnpkg.com/@dcloudio/types/-/types-2.5.9.tgz#06365a3406b02006c76870474314e5c20f24137e"
integrity sha512-dLyZChtY7oZ+34MgWBCU/qAJufszn1XvVN9GXL5Yk2wk/s3vl4kbrB2YDG0pVCUn7cDPmmyRoknp38x/vSAKpQ==
"@eslint/eslintrc@^0.4.3":
version "0.4.3"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册