金诚优选前端代码
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

<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>