167 lines
5.0 KiB
Vue
167 lines
5.0 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="l-tabbar-item" :class="classes">
|
|||
|
|
<view :class="contentClass" :style="[contentStyles]" @click="toggle">
|
|||
|
|
<view class="l-tabbar-item__icon-wrap" :style="[iconStyle]" v-if="icon">
|
|||
|
|
<!-- <l-badge
|
|||
|
|
v-if="(icon || $slots.icon) && (badgeProps.dot || badgeProps.content)"
|
|||
|
|
:dot="badgeProps.dot || false"
|
|||
|
|
:max="badgeProps.max || 99"
|
|||
|
|
:content="badgeProps.content || 0">
|
|||
|
|
<slot icon="icon"></slot>
|
|||
|
|
<l-icon :name="icon"></l-icon>
|
|||
|
|
</l-badge>
|
|||
|
|
<slot icon="icon" v-else-if="$slots.icon"></slot>
|
|||
|
|
<l-icon v-else-if="icon" :name="icon"></l-icon> -->
|
|||
|
|
|
|||
|
|
|
|||
|
|
<template v-if="(icon || $slots.icon) && (badgeProps.dot || badgeProps.content)" >
|
|||
|
|
<l-badge
|
|||
|
|
:dot="badgeProps.dot || false"
|
|||
|
|
:max="badgeProps.max || 99"
|
|||
|
|
:offset="badgeProps.offset || [0, 0]"
|
|||
|
|
:content="badgeProps.content || 0">
|
|||
|
|
<slot name="icon">
|
|||
|
|
<l-icon :name="icon" ></l-icon>
|
|||
|
|
</slot>
|
|||
|
|
</l-badge>
|
|||
|
|
</template>
|
|||
|
|
<template v-else-if="icon || $slots.icon">
|
|||
|
|
<slot name="icon">
|
|||
|
|
<l-icon :name="icon"></l-icon>
|
|||
|
|
</slot>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
</view>
|
|||
|
|
<view class="l-tabbar-item__text"
|
|||
|
|
:class="{
|
|||
|
|
'l-tabbar-item__text--small': !!icon,
|
|||
|
|
'l-tabbar-item__text--only': !icon,
|
|||
|
|
'l-tabbar-item__text--ellipsis': ellipsis
|
|||
|
|
}">
|
|||
|
|
<slot>{{label}}</slot>
|
|||
|
|
</view>
|
|||
|
|
<slot name="extra"></slot>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
<script lang="ts">
|
|||
|
|
// @ts-nocheck
|
|||
|
|
/**
|
|||
|
|
* 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 {ref, defineComponent, computed, inject, getCurrentInstance, onUnmounted} from '@/uni_modules/lime-shared/vue';
|
|||
|
|
import tabbarProps from './props'
|
|||
|
|
import {addUnit} from '@/uni_modules/lime-shared/addUnit'
|
|||
|
|
const name = `l-tabbar-item`
|
|||
|
|
export default defineComponent({
|
|||
|
|
name,
|
|||
|
|
props: tabbarProps,
|
|||
|
|
setup(props) {
|
|||
|
|
const context = getCurrentInstance()
|
|||
|
|
const { split, shape, theme, defaultIndex, activeValue, updateChild, children, activeColor, color, activeBgColor, iconSize, fontSize } = inject('tab-bar');
|
|||
|
|
defaultIndex.value += 1
|
|||
|
|
const currentName = props.value || defaultIndex.value
|
|||
|
|
children.value.push(context.uid)
|
|||
|
|
// 拥挤
|
|||
|
|
const crowded = computed(() => children.value.length > 3)
|
|||
|
|
const isChecked = computed(() => {
|
|||
|
|
return currentName === activeValue.value;
|
|||
|
|
});
|
|||
|
|
const classes = computed(() => {
|
|||
|
|
const cls = [`${name}--${shape.value}`];
|
|||
|
|
if(split.value) {
|
|||
|
|
cls.push(`${name}--split`)
|
|||
|
|
}
|
|||
|
|
if(!props.icon) {
|
|||
|
|
cls.push(`${name}--text-only`)
|
|||
|
|
}
|
|||
|
|
if(crowded.value) {
|
|||
|
|
cls.push(`${name}--crowded`)
|
|||
|
|
}
|
|||
|
|
return cls.join(' ')
|
|||
|
|
// return {
|
|||
|
|
// // [`${name}`]: true,
|
|||
|
|
// [`${name}--split`]: split.value,
|
|||
|
|
// [`${name}--text-only`]: !props.icon,
|
|||
|
|
// [`${name}--crowded`]: crowded.value,
|
|||
|
|
// [`${name}--${shape.value}`]: true,
|
|||
|
|
// }
|
|||
|
|
})
|
|||
|
|
const contentClass = computed(() => {
|
|||
|
|
const cls = [`${name}__content`, `${name}__content--${theme.value}`];
|
|||
|
|
if(isChecked.value) {
|
|||
|
|
cls.push(`${name}__content--checked`)
|
|||
|
|
}
|
|||
|
|
if(props.disabled) {
|
|||
|
|
cls.push(`${name}__content--disabled`)
|
|||
|
|
}
|
|||
|
|
return cls.join(' ')
|
|||
|
|
// return {
|
|||
|
|
// [`${name}__content`]: true,
|
|||
|
|
// [`${name}__content--checked`]: isChecked.value,
|
|||
|
|
// [`${name}__content--disabled`]: props.disabled,
|
|||
|
|
// [`${name}__content--${theme.value}`]: true,
|
|||
|
|
// }
|
|||
|
|
})
|
|||
|
|
const contentStyles = computed(() => {
|
|||
|
|
const style:Record<string, string> = {}
|
|||
|
|
if(fontSize.value) {
|
|||
|
|
style['font-size'] = fontSize.value
|
|||
|
|
}
|
|||
|
|
if(activeBgColor.value) {
|
|||
|
|
style['background'] = activeBgColor.value
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if(activeColor.value || color.value) {
|
|||
|
|
style['color'] = isChecked.value ? activeColor.value : color.value
|
|||
|
|
}
|
|||
|
|
if(activeColor.value) {
|
|||
|
|
style['--l-tabbar-active-color'] = activeColor.value
|
|||
|
|
}
|
|||
|
|
if(color.value) {
|
|||
|
|
style['--l-tabbar-color'] = color.value
|
|||
|
|
}
|
|||
|
|
return style
|
|||
|
|
})
|
|||
|
|
const iconStyle = computed(() => {
|
|||
|
|
const size = addUnit(iconSize.value || (props.icon && !context.slots.default ? 24 : 20))
|
|||
|
|
return {
|
|||
|
|
height: size,
|
|||
|
|
fontSize: size
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
const toggle = () => {
|
|||
|
|
if(props.disabled) return
|
|||
|
|
updateChild(currentName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
onUnmounted(() => {
|
|||
|
|
const index = children.value.indexOf(context.uid);
|
|||
|
|
children.value.splice(index, 1);
|
|||
|
|
})
|
|||
|
|
return {
|
|||
|
|
classes,
|
|||
|
|
contentClass,
|
|||
|
|
contentStyles,
|
|||
|
|
iconStyle,
|
|||
|
|
|
|||
|
|
toggle
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
</script>
|
|||
|
|
<style lang="scss">
|
|||
|
|
@import './index-u';
|
|||
|
|
</style>
|