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

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

需求描述

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

滚动前 滚动后

代码模块

组件代码

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
        })
      },

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

相关推荐
高级程序源3 小时前
django招聘网站信息爬取与分析系统79704-计算机课程设计、毕业设计
后端·python·mysql·小程序·django·flask·课程设计
StevenLdh4 小时前
第四期 · 云端同步与冲突仲裁:离线可写、多端一致的工程解法
java·微信小程序
m0_462803886 小时前
会议签到如何设置手写签名?从创建签到到导出签名 PDF 的完整流程
微信小程序
zhangminghuan7 小时前
UniApp / 微信小程序实战拓展面试题|业务坑点、工程化、跨端踩坑(2026 前端进阶)
小程序
Kingexpand_com15 小时前
企业车队运营痛点解析:传统人工模式如何实现数字化升级
小程序·app·软件开发·app定制开发·打车用车app·车队
2601_949950631 天前
练题簿在线练题全流程:从资料导入到模拟考试与错题复盘
学习·考研·小程序·刷题·小程序推荐
投票竞赛1 天前
线上投票海报生成教程,一键制作带小程序码投票海报
小程序
AI工具人PM产品经理1 天前
零基础微信小程序入门:一个真实项目的里程碑路线图
微信小程序·云开发·学习路线·零基础入门·ai 编程
海鸥两三1 天前
小程序文档预览 · 进阶面试题
小程序·uni-app·uniapp
m0_587383001 天前
上海24小时自助健身房系统软件开发实战指南:从架构到部署
人工智能·小程序·数据挖掘·系统架构·需求分析