| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- <template>
- <view class="nana-tab-bar" :style="{
- ...themeStyles.tabBar.value,
- ...innerStyle,
- ...(fixed ? {
- position: 'fixed',
- bottom: 0,
- left: 0,
- right: 0,
- } : {}),
- paddingBottom: xbarSpace ?
- `${safeAreaBottom}px`
- : themeStyles.tabBar.value.paddingBottom
- }">
- <slot name="background" />
- <slot />
- </view>
- </template>
- <script setup lang="ts">
- import { onMounted, onUpdated, provide, toRefs } from 'vue';
- import { useTheme, type TextStyle, type ViewStyle } from '../theme/ThemeDefine';
- import { DynamicColor, DynamicSize } from '../theme/ThemeTools';
- import { useChildLinkParent } from '../composeabe/ChildItem';
- export interface TabBarProps {
- /**
- * 自定义外层样式
- */
- innerStyle?: ViewStyle;
- /**
- * 选中颜色
- */
- activeColor?: string;
- /**
- * 未选中样式
- */
- inactiveColor?: string;
- /**
- * 标签文字样式
- */
- textStyle?: TextStyle;
- /**
- * 选中的标签名。
- * @default ''
- */
- selectedTabIndex?: number,
- /**
- * 预留底部安全区间距
- * @default false
- */
- xbarSpace?: boolean,
- /**
- * 是否固定在底部
- * @default false
- */
- fixed?: boolean,
- }
- defineOptions({
- options: {
- virtualHost: true,
- styleIsolation: "shared",
- }
- })
- const theme = useTheme();
- const emit = defineEmits([ 'update:selectedTabIndex' ])
- const props = withDefaults(defineProps<TabBarProps>(), {
- activeColor: 'primary',
- inactiveColor: 'text.second',
- })
- const themeStyles = theme.useThemeStyles({
- tabBar: {
- backgroundColor: DynamicColor('TabBarBackgroundColor', 'white'),
- borderTopStyle: 'solid',
- borderTopWidth: DynamicSize('TabBarBorderTopWidth', 2),
- borderTopColor: DynamicColor('TabBarBorderTopColor', 'border.light'),
- paddingTop: DynamicSize('TabBarPaddingVertical', 20),
- paddingBottom: DynamicSize('TabBarPaddingVertical', 20),
- paddingLeft: DynamicSize('TabBarPaddingHorizontal', 0),
- paddingRight: DynamicSize('TabBarPaddingHorizontal', 0),
- },
- });
- const {
- getPosition,
- resetCounter,
- getLength,
- } = useChildLinkParent({
- getPositionExtra(index) {
- return {}
- },
- });
- provide('TabBarContext', {
- topProps: toRefs(props),
- selectTab(index: number) {
- if (props.selectedTabIndex != index)
- emit('update:selectedTabIndex', index);
- },
- getPosition: () => getPosition().index,
- getCount: getLength,
- resetCounter,
- })
- const systemInfo = uni.getWindowInfo();
- const safeAreaBottom = systemInfo.safeAreaInsets?.bottom || 0;// 底部安全区距离
- onMounted(() => {
- resetCounter();
- });
- onUpdated(() => {
- resetCounter();
- });
- </script>
- <style>
- .nana-tab-bar {
- display: flex;
- position: relative;
- flex-direction: row;
- justify-content: space-around;
- align-items: flex-end;
- }
- </style>
|