Initial commit
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<view class="uni-tab-list-root" :class="tabBarRootClass">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 底部选项卡栏
|
||||
* @description 底部选项卡栏组件
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
const tabContentHeightFull = inject<Ref<boolean>>('uniTabContentHeightFull', ref(false))
|
||||
const changeTab = inject<(index: number) => void>('uniTabBarChangeTab', (index: number) => {})
|
||||
|
||||
const itemCount = ref<number>(0)
|
||||
const hasMidButtonItem = ref<boolean>(false)
|
||||
|
||||
const tabBarRootClass = computed(() : string => {
|
||||
return tabContentHeightFull.value ? 'uni-tab-list-root-full' : 'uni-tab-list-root-normal'
|
||||
})
|
||||
|
||||
const validMidButtonLayout = computed(() : boolean => {
|
||||
return hasMidButtonItem.value == false || (itemCount.value > 0 && itemCount.value % 2 == 0)
|
||||
})
|
||||
|
||||
function registerItem() : number {
|
||||
const index = itemCount.value
|
||||
itemCount.value++
|
||||
return index
|
||||
}
|
||||
|
||||
|
||||
function registerMidButton(width : number, height : number) : void {
|
||||
hasMidButtonItem.value = true
|
||||
if (width <= 0) {
|
||||
console.warn('uni-tab-midbutton: width 必须大于 0')
|
||||
}
|
||||
if (height <= 0) {
|
||||
console.warn('uni-tab-midbutton: height 必须大于 0')
|
||||
}
|
||||
}
|
||||
|
||||
function syncOccupiedHeight() : void {
|
||||
if (hasMidButtonItem.value && validMidButtonLayout.value == false) {
|
||||
console.warn('uni-tab-bar: mid-button 需要偶数个普通 uni-tab-item,才能保持居中均分布局')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
syncOccupiedHeight()
|
||||
})
|
||||
|
||||
watch(() : number => itemCount.value, () => {
|
||||
syncOccupiedHeight()
|
||||
})
|
||||
|
||||
watch(() : boolean => hasMidButtonItem.value, () => {
|
||||
syncOccupiedHeight()
|
||||
})
|
||||
|
||||
provide('uniTabListRegisterItem', registerItem)
|
||||
provide('uniTabListRegisterMidButton', registerMidButton)
|
||||
provide('uniTabListChangeTab', changeTab)
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-tab-list-root {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
height: var(--uni-tab-bar-height, 50px);
|
||||
flex-shrink: 0;
|
||||
box-sizing: content-box;
|
||||
padding-bottom: var(--uni-safe-area-inset-bottom);
|
||||
justify-content: flex-start;
|
||||
align-items: flex-end;
|
||||
overflow: visible;
|
||||
border-top-width: 0.5px;
|
||||
border-top-color: rgba(0,0,0,0.33);
|
||||
border-top-style: solid;
|
||||
}
|
||||
|
||||
.uni-tab-list-root-normal {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
/* #ifdef MP-ALIPAY */
|
||||
.uni-tab-list-root-normal {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
.uni-tab-list-root-full {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<view v-if="hasRendered" class="uni-tab-content-root"
|
||||
:style="contentStyle">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 选项卡内容
|
||||
* @description 选项卡内容组件
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
// 从父组件注入数据和方法
|
||||
const currentIndex = inject<Ref<number>>('uniTabBarCurrentIndex', ref(0))
|
||||
const registerContent = inject<() => number>('uniTabBarRegisterContent', () => 0)
|
||||
const tabContentHeightFull = inject<Ref<boolean>>('uniTabContentHeightFull', ref(false))
|
||||
|
||||
// 当前 content 的索引
|
||||
const contentIndex = ref<number>(-1)
|
||||
|
||||
// 是否已经渲染过(按需加载)
|
||||
const hasRendered = ref<boolean>(false)
|
||||
|
||||
// 组件挂载时分配索引
|
||||
onMounted(() => {
|
||||
contentIndex.value = registerContent()
|
||||
|
||||
// 如果是第一个激活的 tab-content,立即渲染
|
||||
if (contentIndex.value == currentIndex.value) {
|
||||
hasRendered.value = true
|
||||
}
|
||||
})
|
||||
|
||||
// 计算是否激活
|
||||
const isActive = computed((): boolean => {
|
||||
return currentIndex.value == contentIndex.value
|
||||
})
|
||||
|
||||
// 监听激活状态,首次激活时渲染
|
||||
watch((): boolean => {
|
||||
return isActive.value
|
||||
}, (newValue: boolean) => {
|
||||
if (newValue && hasRendered.value == false) {
|
||||
hasRendered.value = true
|
||||
}
|
||||
})
|
||||
|
||||
const contentStyle = computed(() => {
|
||||
const active = isActive.value
|
||||
return {
|
||||
visibility: active ? 'visible' : 'hidden',
|
||||
position: active ? 'relative' : 'absolute',
|
||||
left: active ? 'auto' : '0px',
|
||||
top: active ? 'auto' : '0px',
|
||||
right: active ? 'auto' : '0px',
|
||||
bottom: active ? 'auto' : (tabContentHeightFull.value ? '0px' : 'auto')
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-tab-content-root {
|
||||
flex: 1;
|
||||
min-height: 0px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
z-index: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<view class="uni-tab-list-item-root" @click.stop="handleClick">
|
||||
<slot></slot>
|
||||
<text v-if="props.badgeText != null && props.badgeText != '0' && props.badgeText != ''" class="uni-tab-list-item-badge-position uni-tab-list-item-badge-text" :class="props.badgeClass">{{ props.badgeText }}</text>
|
||||
<view v-else-if="props.badgeText != null && props.badgeText != '0'" class="uni-tab-list-item-badge-position uni-tab-list-item-badge-dot" :class="props.badgeClass"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 选项卡项
|
||||
* @description 选项卡项组件
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
defineOptions({
|
||||
externalClasses: ['badge-class']
|
||||
})
|
||||
|
||||
// 定义组件属性
|
||||
type Props = {
|
||||
/**
|
||||
* @description badge 的内容
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
badgeText?: string,
|
||||
/**
|
||||
* @description badge 的样式类
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
badgeClass?: string.ClassString,
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
badgeClass: ''
|
||||
})
|
||||
|
||||
const registerItem = inject<() => number>('uniTabListRegisterItem', () => 0)
|
||||
const changeTab = inject<(index: number) => void>('uniTabListChangeTab', (index: number) => {})
|
||||
const itemIndex = ref<number>(-1)
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
itemIndex.value = registerItem()
|
||||
})
|
||||
|
||||
function handleClick() : void {
|
||||
if (itemIndex.value >= 0) {
|
||||
changeTab(itemIndex.value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-tab-list-item-root {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.uni-tab-list-item-badge-position {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 50%;
|
||||
transform: translate(25%, -50%);
|
||||
}
|
||||
|
||||
.uni-tab-list-item-badge-text {
|
||||
background-color: rgb(225, 80, 80);
|
||||
min-width: 14px;
|
||||
height: 14px;
|
||||
line-height: 14px;
|
||||
border-radius: 7px;
|
||||
font-size: 10px;
|
||||
color: white;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.uni-tab-list-item-badge-dot {
|
||||
background-color: rgb(225, 80, 80);
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
margin-left: 7px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<view :style="{ width: props.width + 'px', height: props.height + 'px' }" class="uni-tab-list-item-midbutton-root">
|
||||
<view class="uni-tab-list-item-midbutton-slot">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 选项卡中间按钮
|
||||
* @description 选项卡中间悬浮按钮组件
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
type Props = {
|
||||
/**
|
||||
* @description 中间按钮宽度,单位 px
|
||||
* @default 90
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
width?: number,
|
||||
/**
|
||||
* @description 中间按钮高度,单位 px
|
||||
* @default 90
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
height?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
width: 90,
|
||||
height: 90
|
||||
})
|
||||
const registerMidButton = inject<(width : number, height : number) => void>('uniTabListRegisterMidButton', (width : number, height : number) => {})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
registerMidButton(props.width, props.height)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-tab-list-item-midbutton-root {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.uni-tab-list-item-midbutton-slot {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: visible;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<view class="uni-tab-bar-root"> <!-- 如果 tab 是一个非全屏的组件,需要套一层。如果是全屏场景,这一层可以省略 -->
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* 选项卡
|
||||
* @description 选项卡容器组件
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
type Props = {
|
||||
/**
|
||||
* @description 当前激活的选项卡索引
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
activeIndex: number,
|
||||
/**
|
||||
* @description tab-content 的高度是否通到tab-bar下面
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
tabContentHeightFull?: boolean
|
||||
}
|
||||
|
||||
// 定义组件属性
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
tabContentHeightFull: false
|
||||
})
|
||||
|
||||
// 定义事件
|
||||
const emit = defineEmits<{
|
||||
/**
|
||||
* @description 选项卡变化时触发,参数为当前激活的选项卡索引,类型为 number
|
||||
* @uniPlatform {
|
||||
* "app": {
|
||||
* "android": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.21"
|
||||
* },
|
||||
* "ios": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.11"
|
||||
* },
|
||||
* "harmony": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07",
|
||||
* "unixVaporVer": "5.07"
|
||||
* }
|
||||
* },
|
||||
* "mp": {
|
||||
* "weixin": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* },
|
||||
* "alipay": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.31"
|
||||
* }
|
||||
* },
|
||||
* "web": {
|
||||
* "uniVer": "x",
|
||||
* "unixVer": "5.07"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
change: [index: number]
|
||||
}>()
|
||||
|
||||
// 当前激活的索引
|
||||
const currentIndex = ref<number>(props.activeIndex)
|
||||
|
||||
const tabContentHeightFull = ref<boolean>(props.tabContentHeightFull)
|
||||
|
||||
// tab-content 的数量计数器
|
||||
const contentCount = ref<number>(0)
|
||||
|
||||
// 监听 activeIndex 变化
|
||||
watch((): number => {
|
||||
return props.activeIndex
|
||||
}, (newIndex: number) => {
|
||||
currentIndex.value = newIndex
|
||||
})
|
||||
|
||||
watch(() : boolean => {
|
||||
return props.tabContentHeightFull
|
||||
}, () => {
|
||||
tabContentHeightFull.value = props.tabContentHeightFull
|
||||
})
|
||||
|
||||
// 切换选项卡
|
||||
function changeTab(index: number): void {
|
||||
if (currentIndex.value != index) {
|
||||
currentIndex.value = index
|
||||
emit('change', index)
|
||||
}
|
||||
}
|
||||
|
||||
// 注册 tab-content
|
||||
function registerContent() : number {
|
||||
const index = contentCount.value
|
||||
contentCount.value++
|
||||
return index
|
||||
}
|
||||
|
||||
// 通过 provide 向子组件提供数据和方法
|
||||
provide('uniTabBarCurrentIndex', currentIndex)
|
||||
provide('uniTabBarChangeTab', changeTab)
|
||||
provide('uniTabBarRegisterContent', registerContent)
|
||||
provide('uniTabContentHeightFull', tabContentHeightFull)
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-tab-bar-root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
min-height: 0px;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user