166 lines
5.8 KiB
Plaintext
166 lines
5.8 KiB
Plaintext
|
|
<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>
|