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