Files
QXTstore/QXTfront/uni_modules/lime-tabbar/components/l-tabbar-item/l-tabbar-item.uvue
2025-11-05 17:34:23 +08:00

166 lines
5.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="l-tabbar-item" :class="classes">
<view :class="contentClass" :style="[contentStyle]" @click="toggle">
<view class="l-tabbar-item__icon-wrap" :style="[iconStyle]" v-if="icon != null || $slots['icon'] != null">
<template v-if="(icon != null || $slots['icon'] != null) && badgeProps?.['dot'] == true || badgeProps?.['content'] != null">
<l-badge
:dot="badgeProps?.['dot'] == true"
:max="badgeProps?.['max'] ?? 99"
:offset="badgeProps?.['offset'] ?? [0, 0]"
:content="badgeProps?.['content']">
<slot name="icon">
<l-icon class="l-tabbar-item__icon"
:class="{'l-tabbar-item__text--checked': isChecked}"
:name="icon" :size="iconSize" :color="colorStyle['color']">
</l-icon>
</slot>
</l-badge>
</template>
<template v-else-if="(icon != null || $slots['icon'] != null)">
<slot name="icon">
<l-icon class="l-tabbar-item__icon"
:class="{'l-tabbar-item__text--checked': isChecked}"
:name="icon" :size="iconSize" :color="colorStyle['color']">
</l-icon>
</slot>
</template>
</view>
<text
v-if="label != null || $slots['default'] != null"
class="l-tabbar-item__text"
:class="{
'l-tabbar-item__text--small': icon != null,
'l-tabbar-item__text--only': icon == null,
'l-tabbar-item__text--checked': isChecked,
'l-tabbar-item__text--ellipsis': ellipsis
}"
:style="[colorStyle, textStyle]">
<slot>{{label}}</slot>
</text>
<slot name="extra"></slot>
</view>
</view>
</template>
<script lang="uts" setup>
/**
* TabbarItem 底部导航项组件
* @description 用于构建Tabbar的单个导航项必须作为Tabbar的子组件使用
* <br>插件类型LTabbarItemComponentPublicInstance
* @tutorial https://ext.dcloud.net.cn/plugin?name=lime-tabbar
*
* @property {Object} badgeProps 徽标配置支持uni-badge所有属性
* @property {string} icon 图标名称支持uni-icons或自定义图标
* @property {string} value 唯一标识符用于v-model绑定
* @property {string} label 文本标签
* @property {boolean} disabled 是否禁用默认false
* @property {boolean} ellipsis 是否超一行省略默认false
*/
import { TabbarProvide } from '../l-tabbar/type';
import { TabbarItemProps } from './type';
import {addUnit} from '@/uni_modules/lime-shared/addUnit'
const themeVars = inject('limeConfigProviderThemeVars', computed(()=> ({})))
const name = 'l-tabbar-item';
const props = withDefaults(defineProps<TabbarItemProps>(), {
disabled: false,
ellipsis: false
})
const instance = getCurrentInstance()!
const parent = inject<TabbarProvide|null>('limeTabbar', null);
const index = ref(0)
const currentName = computed(():string=> props.value ?? `${index.value}`)
// @ts-ignore
const crowded = computed((): boolean => parent != null && parent.children.value.length > 3)
const isChecked = computed((): boolean => currentName.value == parent?.activeValue.value);
const classes = computed(():Map<string, any>=>{
const cls = new Map<string, any>()
const split = parent?.props.split ?? false;
const shape = parent?.props.shape ?? false;
cls.set(`${name}--split`, split);
cls.set(`${name}--${shape}`, true);
cls.set(`${name}--text-only`, props.icon == null)
cls.set(`${name}--crowded`, crowded.value)
return cls
})
const contentClass = computed(():Map<string, any>=> {
const cls = new Map<string, any>()
const theme = parent?.props.theme;
cls.set(`${name}__content`, true)
cls.set(`${name}__content--checked`, isChecked.value)
cls.set(`${name}__content--disabled`, props.disabled)
cls.set(`${name}__content--${theme}`, true)
return cls
})
const contentStyle = computed(():UTSJSONObject=>{
const style = {}
const activeBgColor = parent?.props.activeBgColor;
if(activeBgColor != null && isChecked.value){
style.set('background', activeBgColor)
}
return style
})
const colorStyle = computed(():UTSJSONObject => {
const style = {}
// #ifdef APP
// 安卓 深层文本样式不生效 bug https://issues.dcloud.net.cn/pages/issues/detail?id=11930
const activeColor:any|null = parent?.props.activeColor ?? themeVars.value['tabbarActiveColor'] ?? '#3283ff'
const color:any|null = parent?.props.color ?? themeVars.value['tabbarColor'] ?? 'rgba(0,0,0,0.88)'
// #endif
// #ifndef APP
const activeColor = parent?.props.activeColor
const color = parent?.props.color
// #endif
if(activeColor != null && isChecked.value){
style.set('color', `${activeColor}`)
}
if(color != null && !isChecked.value){
style.set('color', `${color}`)
}
return style
})
const textStyle = computed(():UTSJSONObject=>{
const style = {}
const fontSize = parent?.props.fontSize
if(fontSize != null){
style.set('font-size', fontSize)
}
return style
})
// @ts-ignore
const iconSize = computed(():string => addUnit(parent?.props.iconSize ?? (props.icon !=null && instance.slots['default'] == null ? 24 : 20))!)
const iconStyle = computed(():Map<string, any> =>{
const style = new Map<string, any>()
style.set('height', iconSize.value);
return style
})
const toggle = ()=>{
if(props.disabled || isChecked.value || parent == null) return
parent.updateChild(currentName.value)
// parent!.activeValue.value = currentName.value
}
onMounted(()=>{
if(parent == null) return
parent.defaultIndex.value +=1;
index.value = parent.defaultIndex.value;
parent.children.value.push(instance.proxy! as LTabbarItemComponentPublicInstance)
})
onUnmounted(()=>{
// @ts-ignore
if(parent == null) return
const _index = parent.children.value.indexOf(instance.proxy! as LTabbarItemComponentPublicInstance);
parent.children.value.splice(_index, 1);
})
</script>
<style lang="scss">
@import './index-u';
</style>