You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
6.6 KiB
259 lines
6.6 KiB
<template>
|
|
<view ref="item"
|
|
:class="[
|
|
'lb-tabbar-item',
|
|
'animate__animated',
|
|
isActive ? 'lb-tabbar-item--active' : ''
|
|
]"
|
|
:style="{
|
|
paddingTop: paddingBT + raisedeHeight + 'px',
|
|
paddingBottom: paddingBT + 'px',
|
|
width: '100%'
|
|
}"
|
|
@tap="handleTap">
|
|
<view :class="[
|
|
'lb-tabbar-item__icon',
|
|
`lb-tabbar-item__icon--${raisede ? 'raisede' : 'default'}`,
|
|
isAnimate ? `animate__animated animate__${tabbarInfo.animate}` : '',
|
|
isActive ? 'lb-my-active' : ''
|
|
]"
|
|
:style="{
|
|
height: tabbarInfo.iconSize,
|
|
lineHeight: tabbarInfo.iconSize,
|
|
transform: raisede ? `translateY(-${ty}px) scale(${tabbarInfo.raisedeScale})` : ''
|
|
}">
|
|
<!-- 图片图标 -->
|
|
<image v-if="isImage"
|
|
class="lb-tabbar-item__image"
|
|
:src="icon"
|
|
:style="{
|
|
width: tabbarInfo.iconSize,
|
|
height: tabbarInfo.iconSize
|
|
}">
|
|
</image>
|
|
|
|
<!-- icon图标 -->
|
|
<text v-else
|
|
:class="[
|
|
'lf-iconfont',
|
|
iconPrefix,
|
|
`${iconPrefix}-${icon}`,
|
|
isActive ? 'lb-tabbar-item__icon--active' : ''
|
|
]"
|
|
:style="{
|
|
width: tabbarInfo.iconSize,
|
|
height: tabbarInfo.iconSize,
|
|
lineHeight: tabbarInfo.iconSize,
|
|
fontSize: tabbarInfo.iconSize,
|
|
color: isActive ? tabbarInfo.activeColor : tabbarInfo.inactiveColor
|
|
}">{{ iconCode }}</text>
|
|
|
|
<!-- 非nvue dot info显示 -->
|
|
<!-- #ifndef APP-NVUE -->
|
|
<text v-if="dot || hasInfo"
|
|
:class="[
|
|
dot && !hasInfo ? 'lb-tabbar-item__dot' : '',
|
|
hasInfo ? 'lb-tabbar-item__dot--info' : '',
|
|
'lb-tabbar-item__dot--style'
|
|
]"
|
|
:style="{
|
|
backgroundColor: tabbarInfo.dotColor
|
|
}">{{ hasInfo ? info : '' }}</text>
|
|
<!-- #endif -->
|
|
</view>
|
|
|
|
<!-- nvue dot info 显示 -->
|
|
<!-- #ifdef APP-NVUE -->
|
|
<text v-if="dot || hasInfo"
|
|
:class="[
|
|
'lb-tabbar-item__dot--nvue',
|
|
'lb-tabbar-item__dot--style',
|
|
dot && !hasInfo ? 'lb-tabbar-item__dot' : '',
|
|
hasInfo ? 'lb-tabbar-item__dot--info' : '',
|
|
hasInfo ? 'lb-tabbar-item__dot--info' : '',
|
|
nvueDotShow ? 'lb-tabbar-item__dot--show' : ''
|
|
]"
|
|
:style="{
|
|
backgroundColor: tabbarInfo.dotColor,
|
|
top: paddingBT + raisedeHeight + 'px',
|
|
right: dotLeft + 'px'
|
|
}">{{ hasInfo ? info : '' }}</text>
|
|
<!-- #endif -->
|
|
|
|
<!-- 非nvue图标文字 -->
|
|
<!-- #ifndef APP-NVUE -->
|
|
<view :class="[
|
|
'lb-tabbar-item__text',
|
|
isActive ? 'lb-tabbar-item__text--active' : ''
|
|
]"
|
|
:style="{
|
|
fontSize: tabbarInfo.textSize,
|
|
lineHeight: tabbarInfo.textSize,
|
|
maxHeight: tabbarInfo.textSize,
|
|
marginTop: tabbarInfo.textTop,
|
|
color: isActive
|
|
? tabbarInfo.activeTextColor || tabbarInfo.activeColor
|
|
: tabbarInfo.inactiveTextColor || tabbarInfo.inactiveColor
|
|
}">
|
|
<slot></slot>
|
|
<view v-if="raisede"
|
|
class="lb-tabbar-item__text--block"
|
|
:style="{
|
|
height: tabbarInfo.textSize
|
|
}">
|
|
</view>
|
|
</view>
|
|
<!-- #endif -->
|
|
|
|
<!-- nvue图标文字 -->
|
|
<!-- #ifdef APP-NVUE -->
|
|
<text v-if="text || raisede"
|
|
:class="[
|
|
'lb-tabbar-item__text',
|
|
isActive ? 'lb-tabbar-item__text--active' : ''
|
|
]"
|
|
:style="{
|
|
fontSize: tabbarInfo.textSize,
|
|
height: tabbarInfo.textSize,
|
|
lineHeight: tabbarInfo.textSize,
|
|
marginTop: tabbarInfo.textTop,
|
|
color: isActive
|
|
? tabbarInfo.activeTextColor || tabbarInfo.activeColor
|
|
: tabbarInfo.inactiveTextColor || tabbarInfo.inactiveColor
|
|
}">{{ text || '' }}</text>
|
|
<!-- #endif -->
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
// #ifdef APP-NVUE
|
|
const dom = uni.requireNativePlugin('dom')
|
|
// #endif
|
|
import { getPx } from './utils'
|
|
export default {
|
|
props: {
|
|
name: [String, Number],
|
|
text: [String, Number],
|
|
icon: String,
|
|
iconPrefix: String,
|
|
dot: Boolean,
|
|
info: [String, Number],
|
|
raisede: Boolean,
|
|
path: String
|
|
},
|
|
inject: ['tabbar'],
|
|
data () {
|
|
return {
|
|
tabbarInfo: {},
|
|
itemWidth: 0,
|
|
dotLeft: 0,
|
|
nvueDotShow: false
|
|
}
|
|
},
|
|
computed: {
|
|
isImage () {
|
|
return this.icon && this.icon.indexOf('/') > -1
|
|
},
|
|
isActive () {
|
|
return this.tabbarInfo.value === this.name
|
|
},
|
|
isAnimate () {
|
|
return (
|
|
this.isActive &&
|
|
this.tabbarInfo.animate &&
|
|
!(this.raisede && this.tabbarInfo.closeAnimateOnRaisede)
|
|
)
|
|
},
|
|
height () {
|
|
return getPx(this.tabbarInfo.height)
|
|
},
|
|
iconHeight () {
|
|
return getPx(this.tabbarInfo.iconSize)
|
|
},
|
|
textSize () {
|
|
return getPx(this.tabbarInfo.textSize)
|
|
},
|
|
textTop () {
|
|
return getPx(this.tabbarInfo.textTop)
|
|
},
|
|
ty () {
|
|
return this.height / 2 - (this.textSize + this.textTop) / 2
|
|
},
|
|
iconCode () {
|
|
let code = ''
|
|
// #ifdef APP-NVUE
|
|
code = this.icon
|
|
// #endif
|
|
return code
|
|
},
|
|
hasInfo () {
|
|
return this.info || this.info === 0
|
|
},
|
|
paddingBT () {
|
|
return (this.height - this.iconHeight - this.textSize - this.textTop) / 2
|
|
},
|
|
hasRaisede () {
|
|
return this.tabbar.hasRaisede
|
|
},
|
|
raisedeHeight () {
|
|
return this.hasRaisede ? this.iconHeight * this.tabbarInfo.raisedeScale / 2 : 0 // 凸起高度
|
|
},
|
|
infoLength () {
|
|
return this.hasInfo ? (this.info + '').length : 0
|
|
}
|
|
},
|
|
created () {
|
|
this.tabbarInfo = this.tabbar._props
|
|
this.tabbar.tabbarItems.push(this._props)
|
|
},
|
|
mounted() {
|
|
// #ifdef APP-NVUE
|
|
this.setNvueDot()
|
|
// #endif
|
|
},
|
|
methods: {
|
|
handleTap () {
|
|
this.tabbar.active = this.name
|
|
this.$emit('click', this._props)
|
|
},
|
|
// #ifdef APP-NVUE
|
|
setNvueDot () {
|
|
if (this.dot || this.hasInfo) {
|
|
this.$nextTick(() => {
|
|
const $el = this.$refs.item
|
|
dom.getComponentRect($el, res => {
|
|
this.itemWidth = res.size.width
|
|
const halfWidth = this.itemWidth / 2
|
|
if (this.dot) {
|
|
this.dotLeft = halfWidth - 8
|
|
}
|
|
if (this.hasInfo) {
|
|
const length = this.infoLength > 1 ? this.infoLength -1 : this.infoLength
|
|
this.dotLeft = halfWidth - 8 * length
|
|
}
|
|
this.nvueDotShow = true
|
|
})
|
|
})
|
|
}
|
|
}
|
|
// #endif
|
|
},
|
|
// #ifdef APP-NVUE
|
|
watch: {
|
|
dot () {
|
|
this.setNvueDot()
|
|
},
|
|
info () {
|
|
this.setNvueDot()
|
|
}
|
|
}
|
|
// #endif
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "./style.scss";
|
|
/* #ifndef APP-NVUE */
|
|
@import "./animate.scss";
|
|
/* #endif */
|
|
</style>
|