微信小程序自定义标题背景色

原生的微信小程序是不支持自定义标题背景色的,因此需要自己封装一个标题组件;

需求描述

微信小程序标题默认透明,底色为整体视口的背景色,当页面超出视口长度滚动时标题背景色由透明色变为白色,实现效果大致如下所示:

滚动前 滚动后

代码模块

组件代码

javascript 复制代码
<template>
  <view class="custom-nav-bar" wx:style="{{ { top: searchTop + 'px' } }}">
    <van-icon size="40rpx" bind:tap="onTap" class="arrow" name="{{iconName}}" />
    <text class="nav-title">{{title}}</text>
  </view>
  <!-- 向上滚动后,展示白的的导航栏 -->
  <view
    class="nav-bar-white"
    wx:style="{{ { opacity: whiteBgOpacity, paddingTop: searchTop + 'px' } }}"
  >
    <van-icon size="40rpx" bind:tap="onTap" class="arrow" name="{{iconName}}" />
    <text class="nav-title">{{title}}</text>
  </view>
</template>
<script type="application/json">
  {
    "usingComponents": {
      "van-icon": "@vant/weapp/dist/icon/index",
    },
    "navigationStyle": "custom"
  }
</script>
<script>
  import { createComponent } from '@mpxjs/core'

  createComponent({
    properties: {
      // 判断是否展示白色标题
      whiteBgOpacity: {
        type: String,
        observer: function (newVal, oldVal) {}
      },
      // 页面标题
      title: {
        type: String,
        observer: function (newVal, oldVal) {}
      },
      // 导航icon
      iconName: {
        type: String,
        observer: function (newVal, oldVal) {}
      }
    },
    data() {
      return {
        searchTop: 0
        // whiteBgOpacity: 0,
      }
    },
    ready() {
      this.getBarInfo()
    },
    methods: {
      getBarInfo() {
        const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
        const whiteBarHeight = menuButtonInfo.top + menuButtonInfo.height
        this.triggerEvent('childEvent', whiteBarHeight)
        this.setData({
          searchTop: menuButtonInfo.top
        })
      },
      onTap() {
        this.triggerEvent('handleIconTap')
      }
    }
  })
</script>
<style lang="scss" scoped>
  .custom-nav-bar {
    position: fixed;
    /* top: 70rpx; */
    width: 100%;
    display: flex;
    color: #000000;
    justify-content: space-between;
    align-items: center;
    height: 64rpx;
    .arrow {
      position: absolute;
      width: 48rpx;
      height: 48rpx;
      margin-right: 48rpx;
    }
    .nav-title {
      margin: 0 auto;
      font-size: 34rpx;
      font-weight: 500;
      color: #000000;
    }
  }
  .nav-bar-white {
    position: fixed;
    top: 0;
    width: 100%;
    height: 68rpx;
    background: #fff;
    z-index: 10001;
    display: flex;
    align-items: center;
    font-size: 34rpx;
    font-weight: 500;
    .arrow {
      width: 48rpx;
      height: 48rpx;
      position: absolute;
    }
    .nav-title {
      text-align: center;
      flex: 1;
      font-size: 34rpx;
      font-weight: 500;
    }
  }
</style>

​

引用代码

javascript 复制代码
<template>
  <scroll-view
    class="my-scroll-view"
    scroll-y="{{true}}"
    bindscroll="onScroll"
    bindscrolltolower="onScrollToLower"
  >
    <view
      class="record-page-container"
      wx:style="{{ { paddingTop: whiteBarHeight + 'px' } }}"
      style="{{recordPageContainerCss}}"
    >
      <header
        whiteBgOpacity="{{whiteBgOpacity}}"
        iconName="arrow-left"
        bind:handleIconTap="onBack"
        title="过磅记录"
        bind:childEvent="handleChildEvent"
      />
    </view>
  </scroll-view>
</template>
<template>
  <scroll-view
    class="my-scroll-view"
    scroll-y="{{true}}"
    bindscroll="onScroll"
    bindscrolltolower="onScrollToLower"
  >
    <view
      class="record-page-container"
      wx:style="{{ { paddingTop: whiteBarHeight + 'px' } }}"
      style="{{recordPageContainerCss}}"
    >
      <header
        whiteBgOpacity="{{whiteBgOpacity}}"
        iconName="arrow-left"
        bind:handleIconTap="onBack"
        title="过磅记录"
        bind:childEvent="handleChildEvent"
      />
    </view>
  </scroll-view>
</template>

<script>
  import { createPage } from '@mpxjs/core'
  createPage({
    data: {
      whiteBarHeight: 0
    },
    onHide() {},
    onUnload() {},
    onLoad() {},
    async onShow() {},
    onReady() {},

    methods: {
      handleChildEvent(e) {
        this.setData({
          whiteBarHeight: e.detail
        })
      },
      onScroll(e) {
        const { scrollTop } = e.detail || {}
        this.setData({
          whiteBgOpacity: scrollTop < 10 ? 0 : 1
        })
      },
      onBack() {
        wx.navigateBack()
      }
    }
  })
</script>

<script type="application/json">
  {
    "usingComponents": {
      "van-button": "@vant/weapp/dist/button/index",
      "van-cell-group": "@vant/weapp/dist/cell-group/index",
      "van-field": "@vant/weapp/dist/field/index",
      "van-cell": "@vant/weapp/dist/cell/index",
      "van-icon": "@vant/weapp/dist/icon/index",
      "van-loading": "@vant/weapp/dist/loading/index",
      "van-action-sheet": "@vant/weapp/dist/action-sheet/index",
      "van-datetime-picker": "@vant/weapp/dist/datetime-picker/index",
      "header": "../../components/header/index.mpx"
    },
    "disableScroll": true,
    "navigationBarTitleText": "过磅记录",
    "navigationStyle": "custom"
  }
</script>
<style lang="scss" scoped>
  .record-page-container {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    width: 100vw;
    height: 100vh;
    // padding: 0 12px;
    background-size: 100% auto;
    background-repeat: no-repeat;
    background-position: top left;
    box-sizing: border-box;

    .my-scroll-view {
      width: 100vw;
      // box-sizing: border-box;
    }
  }
</style>

上述两个代码中子组件通过属性方式将展示的标题和icon以及点击icon需要触发的操作进行接收,并在初始化后 ​​ready ​​方法只用过计算出当前菜单按钮(右上角的多点菜单按钮)的位置和尺寸,并通过​​childEvent​​方法【告诉】父组件,并让父组件通过 ​​padding-top​​ 的方式给​​header​​组件留出位置。

至于子组件的标题是否展示白色还是透明色,通过父组件的 ​​onScroll ​​方法判断:

javascript 复制代码
onScroll(e) {
        const { scrollTop } = e.detail || {}
        this.setData({
          whiteBgOpacity: scrollTop < 10 ? 0 : 1
        })
      },

当页面滚动到一定位置时,白色标题展示。

相关推荐
ngaiwe4 小时前
AA我来算小程序实践:把付款人、承担人和结算状态分开建模
微信小程序
FX1317887KP_10 小时前
KET口语Part 2看图对话怎么练?“观察—提问—回应”;三步法讲透
小程序·ket口语·pet口语·fce备考·剑桥英语
上线再说14 小时前
小程序图片处理从 2.9 秒到 420 毫秒:云函数冷启动的 5 个坑
微信小程序
沃达德软件14 小时前
智慧教育教学资源管理系统(PC端+微信小程序)
微信小程序·小程序
阿俊-全栈开发16 小时前
LikeShop 小程序商城首页可配置弹窗的设计与实现(Java + uni-app)
小程序·状态模式·likeshop·likeshop开源商城
考拉讲支付1 天前
延迟分账 / 核销分账的技术实现方案:服务完成后再分钱,到底怎么设计?
大数据·运维·人工智能·微信小程序·小程序·系统架构
Newway3212 天前
便利店小程序商城如何打通总部、门店与会员
小程序·小程序商城·会员运营·连锁便利店·门店订货·o2o系统
Strawberry962 天前
小程序视频播放官方方案
小程序
weixin_177297220692 天前
二手旧物回收小程序先要解决的不是下单,是“上门之后价格变了怎么办“
小程序·apache
青企通2 天前
电动车门店小程序:以旧换新估价、维修工单与电池档案的设计实现
小程序