VUE项目H5沉浸式导航(可设置是否站位、可设置是否固定颜色、可设置背景图、可透明变有颜色、可有颜色变另一种颜色、可使用插槽)

本文介绍了Vue组件NavBarH5.vue,它是一个可定制的H5导航栏,支持状态栏和导航栏高度的UA兼容,通过滚动高度实现颜色渐变效果,提供了自定义回退和分享功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue组件:NavBarH5.vue

<!-- H5导航(UA中获取状态栏和导航栏高度,做版本兼容) -->
<template>
  <div
    :style="{'position': positionType,'padding-top': `${paddingTop}px`,'height': `${navBarHeight}px`, 'background-color': bgColor,'background-image': bgImg,'z-index': zIndex,'color': textColor,'border-bottom': borderBottom}"
    class="navBar"
  >
    <!-- 左侧回退部分 -->
    <div class="leftBox">
      <slot name="left">
        <van-icon :size="22" name="arrow-left" @click="handleBack"/>
      </slot>
    </div>

    <!-- 标题部分 -->
    <div :style="{ color: titleColor,'height': `${navBarHeight}px` }" class="titleBox">
      <slot name="title">
        <div class="van-ellipsis">
          {{ title }}
        </div>
      </slot>
    </div>

    <!-- 右侧分享部分 -->
    <div v-if="isRightShow" class="rightBox">
      <slot name="right">
        <i class="iconfont icon-share shareIcon" @click="handleShare"></i>
      </slot>
    </div>
  </div>
</template>

<script>
import headerTop from '@/mixin/headerTop'

export default {
  name: 'NavBar',

  mixins: [headerTop],

  props: {
    // 是否导航条是否有高度
    placeholder: {
      type: Boolean,
      default: false
    },
    // 导航定位层级
    zIndex: {
      type: Number,
      default: 999999
    },
    // 标题
    title: {
      type: String,
      default: '标题'
    },
    // 是否显示右侧内容
    isRightShow: {
      type: Boolean,
      default: true
    },
    // 变化开始高度
    startHeight: {
      type: Number,
      default: 0
    },
    // 变化结束时的高度
    endHeight: {
      type: Number,
      default: 100
    },
    // 开始背景颜色
    startBgColor: {
      type: String,
      default: ''
    },
    // 结束背景颜色
    endBgColor: {
      type: String,
      default: ''
    },
    // 开始文字颜色
    startTextColor: {
      type: String,
      default: '33,38,52'
    },
    // 结束文字颜色
    endTextColor: {
      type: String,
      default: ''
    },
    // 标题结束颜色
    endTitleColor: {
      type: String,
      default: ''
    },
    // 是否自定义返回按钮
    isCustomizeBack: {
      type: Boolean,
      default: false
    },
    // 背景图片
    navBarBgImg: {
      type: String,
      default: ''
    },
    // 底部边框
    borderBottom: {
      type: String,
      default: 'unset'
    }
  },

  data () {
    return {
      scrollHeight: 0, // 滑动高度
      statusBarH: this.$bridgeCompat.UA_CONSTANT.statusBar, // 状态栏高度
      navBarH: this.$bridgeCompat.UA_CONSTANT.navBarH // 导航栏高度
    }
  },

  computed: {
    // 是否占位置
    positionType () {
      return this.placeholder ? 'relative' : 'fixed'
    },
    // 沉浸式导航顶部内边距(状态栏高度)
    paddingTop () {
      return this.statusBarH ? this.statusBarH : this.topNum ? this.topNum : 0
    },
    // 导航栏高度
    navBarHeight () {
      return this.navBarH ? this.navBarH : 44
    },
    // 导航栏整体高度,给父组件用(注意单位:px)
    integralHeight () {
      return this.navBarHeight + this.paddingTop
    },
    // 背景颜色计算
    bgColor () {
      if (!this.startBgColor && this.endBgColor) {
        // 透明变有颜色
        return this.opacityChange('bg', this.scrollHeight)
      } else if (this.startBgColor && !this.endBgColor) {
        // 有颜色不变化
        return `rgb(${this.startBgColor})`
      } else if (this.startBgColor && this.endBgColor) {
        // 有颜色变化
        return this.colorChange('bg', this.scrollHeight)
      } else {
        // 透明不变化
        return `rgba(0, 0, 0, 0)`
      }
    },
    // 字体颜色计算
    textColor () {
      if (!this.startTextColor && this.endTextColor) {
        // 透明变有颜色
        return this.opacityChange('text', this.scrollHeight)
      } else if (this.startTextColor && !this.endTextColor) {
        // 有颜色不变化
        return `rgb(${this.startTextColor})`
      } else if (this.startTextColor && this.endTextColor) {
        // 有颜色变化
        return this.colorChange('text', this.scrollHeight)
      } else {
        // 透明不变化
        return `rgba(0, 0, 0, 0)`
      }
    },
    // 背景图计算
    bgImg () {
      return this.navBarBgImg ? `url(${this.navBarBgImg})` : 'unset'
    },
    // 标题颜色计算
    titleColor () {
      if (this.endTitleColor) {
        // 透明变有颜色
        return this.opacityChange('title', this.scrollHeight)
      } else {
        // 不设置颜色
        return ''
      }
    }
  },

  watch: {
    // 监听整体高度,为父组件提供导航栏高度
    integralHeight: {
      immediate: true,
      handler (newValue) {
        if (newValue) {
          this.$emit('getNavBarIntegralHeight', newValue)
        }
      }
    }
  },

  methods: {
    // 设置滑动高度
    setScrollHeight (scrollHeight) {
      if (scrollHeight >= 0) {
        this.scrollHeight = scrollHeight
      }
    },

    // 有颜色变有颜色
    colorChange (flag, scrollHeight) {
      let startBgArr, endBgArr

      if (flag === 'bg') {
        startBgArr = this.startBgColor.split(',')
        endBgArr = this.endBgColor.split(',')
      } else if (flag === 'text') {
        startBgArr = this.startTextColor.split(',')
        endBgArr = this.endTextColor.split(',')
      }

      let changeR, changeG, changeB

      if (scrollHeight < this.startHeight) {
        changeR = startBgArr[0]
        changeG = startBgArr[1]
        changeB = startBgArr[2]
      } else if (
        scrollHeight >= this.startHeight &&
        scrollHeight <= this.endHeight
      ) {
        let changeRatio = scrollHeight / (this.endHeight - this.startHeight)

        changeR =
          ~~((endBgArr[0] - startBgArr[0]) * changeRatio) +
          parseInt(startBgArr[0])
        changeG =
          ~~((endBgArr[1] - startBgArr[1]) * changeRatio) +
          parseInt(startBgArr[1])
        changeB =
          ~~((endBgArr[2] - startBgArr[2]) * changeRatio) +
          parseInt(startBgArr[2])
      } else {
        changeR = endBgArr[0]
        changeG = endBgArr[1]
        changeB = endBgArr[2]
      }

      return `rgb(${changeR},${changeG},${changeB})`
    },

    // 透明变有颜色
    opacityChange (flag, scrollHeight) {
      let changeA

      if (scrollHeight < this.startHeight) {
        changeA = 0
      } else if (scrollHeight >= this.startHeight && scrollHeight <= this.endHeight) {
        changeA = (scrollHeight / (this.endHeight - this.startHeight)).toFixed(
          2
        )
      } else {
        changeA = 1
      }

      if (flag === 'bg') {
        return `rgba(${this.endBgColor},${changeA})`
      } else if (flag === 'text') {
        return `rgba(${this.endTextColor},${changeA})`
      } else if (flag === 'title') {
        return `rgba(${this.endTitleColor},${changeA})`
      }
    },

    // 回退按钮
    handleBack () {
      if (this.isCustomizeBack) {
        this.$emit('customizeBack')
      } else {
        this.$thfund.closeWindow()
      }
    },

    // 点击分享按钮
    handleShare () {
      this.$emit('handleShare')
    }
  }
}
</script>

<style lang="scss" scoped>
.navBar {
  left: 0;
  top: 0;
  right: 0;
  font-size: 12px;
  line-height: 1.2;
  padding: 0 0.15rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;

  // 左侧回退部分
  .leftBox {
    i {
      vertical-align: middle;
    }
  }

  // 标题部分
  .titleBox {
    position: absolute;
    bottom: 0;
    left: 50%;
    z-index: 10;
    transform: translateX(-50%);
    font-size: 16px;
    text-align: center;
    max-width: 2.5rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  // 右侧分享部分
  .rightBox {
    .shareIcon {
      font-size: 20px;
      vertical-align: middle;
    }
  }
}
</style>

使用导航头组件
template中

<NavBarH5
        v-show="!fullScreenShow"
        ref="NavBarH5"
        :endHeight="80"
        :isCustomizeBack="true"
        :zIndex="9999999999999999"
        endBgColor="255,255,255"
        endTextColor="33,38,52"
        startBgColor="236,47,60"
        startTextColor="255,255,255"
        @customizeBack="handleBack"
        @handleShare="handleShare">
        <template slot="title">
          <div style="font-size: 0.1rem;">
            <div
              style="font-size: 0.14rem;font-weight: 700;margin-bottom: .02rem;"
            >
              {{ fundName }}
            </div>
            <span>{{ ajaxFundCode }}</span>
          </div>
        </template>

        <template slot="right">
<!--          <div><span style="font-size: 20px;margin-top: -2px;" class="iconfont icon-fenxiang"></span></div>-->
          <div style="font-size: 24px;margin-top: -2px;"><van-icon name="share-o" /></div>
        </template>
      </NavBarH5>

script中

import NavBarH5 from '@/components/NavBarH5'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值