全局自动下拉变色解决方案
雀语文章地址
📖 项目简介
这是一个基于 Vue.js 和 uni-app 的全局自动下拉变色解决方案,通过全局 mixin 实现页面滚动时导航栏的自动颜色变化效果。
✨ 核心特性
● 🎯 全局自动生效:无需在每个页面手动导入,自动为所有页面添加滚动监听
● 🎨 智能颜色变化:根据滚动位置自动调整导航栏背景色和文字颜色
● 📱 跨平台兼容:支持微信小程序、H5、App 等多端
● ⚡ 性能优化:使用节流函数优化滚动事件处理
● 🔧 易于配置:支持自定义颜色配置和触发阈值
🏗️ 项目结构
buddhism/
├── mixins/
│ └── page-scroll-mixin.js # 全局滚动监听 mixin
├── components/
│ └── custom-navbar/
│ └── custom-navbar.vue # 自定义导航栏组件
├── main.js # 全局 mixin 注册
└── pages/
└── basePage/
└── basePage.vue # 示例页面
🚀 快速开始

  1. 安装依赖

  2. 全局配置
    在 main.js 中已经配置了全局 mixin:

import PageScrollMixin from './mixins/page-scroll-mixin.js'// 注册全局 mixin
Vue.mixin(PageScrollMixin)
  1. 使用导航栏组件
    在任何页面中直接使用 custom-navbar 组件:
<template><view class="page"><!-- 自定义导航栏 --><custom-navbar title="页面标题":show-back="true"@back="goBack"ref="customNavbar"//必写/><!-- 页面内容 --><view class="content"><!-- 你的页面内容 --></view></view>
</template>
<script>
export default {name: 'YourPage',methods: {goBack() {uni.navigateBack()}}
}
</script>

📋 核心文件说明

  1. mixins/page-scroll-mixin.js
    全局滚动监听 mixin,为所有页面提供滚动事件处理:
export default {data() {return {scrollTop: 0,navbarOpacity: 0,navbarTextColor: '#000000',navbarBgColor: 'rgba(255, 255, 255, 0)'}},onPageScroll(e) {this.handlePageScroll(e)},methods: {handlePageScroll(e) {// 节流处理滚动事件if (this.scrollTimer) returnthis.scrollTimer = setTimeout(() => {this.scrollTop = e.scrollTopthis.updateNavbarStyle()this.scrollTimer = null}, 16) // 约60fps},updateNavbarStyle() {// 根据滚动位置更新导航栏样式const opacity = Math.min(this.scrollTop / 100, 1)this.navbarOpacity = opacityif (opacity > 0.5) {this.navbarTextColor = '#000000'this.navbarBgColor = `rgba(255, 255, 255, ${opacity})`} else {this.navbarTextColor = '#ffffff'this.navbarBgColor = `rgba(255, 255, 255, ${opacity})`}}}
}
  1. components/custom-navbar/custom-navbar.vue
    自定义导航栏组件,支持动态样式变化:
<template><view class="custom-navbar":style="navbarStyle"><view class="navbar-content"><view v-if="showBack" class="back-btn"@click="handleBack"><text class="back-icon"></text></view><text class="navbar-title":style="{ color: navbarTextColor }">{{ title }}</text></view></view>
</template>
<script>
export default {name: 'CustomNavbar',props: {title: {type: String,default: ''},showBack: {type: Boolean,default: false}},computed: {navbarStyle() {return {backgroundColor: this.navbarBgColor,color: this.navbarTextColor}}},methods: {handleBack() {this.$emit('back')}}
}
</script>

🎨 自定义配置
修改颜色配置
在 mixins/page-scroll-mixin.js 中可以自定义颜色:

updateNavbarStyle() {const opacity = Math.min(this.scrollTop / 100, 1)this.navbarOpacity = opacity// 自定义颜色逻辑if (opacity > 0.5) {this.navbarTextColor = '#333333'  // 深色文字this.navbarBgColor = `rgba(255, 255, 255, ${opacity})`} else {this.navbarTextColor = '#ffffff'  // 白色文字this.navbarBgColor = `rgba(0, 0, 0, ${opacity * 0.3})`}
}

修改触发阈值
调整滚动距离阈值:


// 将 100 改为你想要的阈值
const opacity = Math.min(this.scrollTop / 50, 1)  // 50px 开始变化

📱 使用示例
基础页面

<template><view class="page"><custom-navbar title="首页":show-back="false"ref="customNavbar"//必写/><view class="content"><view class="banner"><image src="/static/banner.jpg" mode="aspectFill" /></view><view class="list"><view v-for="item in 20" :key="item"class="list-item">列表项 {{ item }}</view></view></view></view>
</template>
<script>
export default {name: 'HomePage'
}
</script>
<style scoped>
.page {min-height: 100vh;background: #f5f5f5;
}.content {padding-top: 44px; /* 导航栏高度 */
}.banner {height: 200px;background: linear-gradient(45deg, #667eea, #764ba2);
}.list-item {padding: 15px;margin: 10px;background: white;border-radius: 8px;box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
</style>详情页面
<template><view class="page"><custom-navbar title="详情页":show-back="true"@back="goBack"/><view class="content"><view class="hero-image"><image src="/static/detail.jpg" mode="aspectFill" /></view><view class="detail-content"><text class="title">详情标题</text><text class="description">详情描述内容...</text></view></view></view>
</template>
<script>
export default {name: 'DetailPage',methods: {goBack() {uni.navigateBack()}}
}
</script>

🔧 技术实现
核心原理

  1. 全局 Mixin:通过 Vue 的全局 mixin 机制,为所有页面自动注入滚动监听
  2. 节流优化:使用 setTimeout 实现 60fps 的滚动事件节流
  3. 动态样式:根据滚动位置计算透明度,实现平滑的颜色过渡
  4. 响应式数据:通过 Vue 的响应式系统,自动更新导航栏样式
    性能优化
    ● ✅ 滚动事件节流(16ms 间隔)
    ● ✅ 使用 computed 属性缓存样式计算
    ● ✅ 避免频繁的 DOM 操作
    ● ✅ 合理的内存管理
    🐛 常见问题
    Q: 导航栏不显示?
    A: 确保页面内容有足够的高度可以滚动,并且设置了正确的 padding-top
    Q: 颜色变化不明显?
    A: 检查背景图片的对比度,可以调整颜色配置或透明度
    Q: 在某些页面不需要效果?
    A: 可以在特定页面中覆盖 mixin 的方法:
    export default {
    onPageScroll() {
    // 覆盖全局 mixin,不执行滚动处理
    }
    }

🤝 贡献
欢迎提交 Issue 和 Pull Request!

注意:此解决方案专为 uni-app 项目设计,确保在目标平台上测试兼容性。

全局导航栏组件,自动实现下拉透明到纯色

import PageScrollMixin from './mixins/page-scroll-mixin.js'// 注册全局 mixin
Vue.mixin(PageScrollMixin)
/*** 页面滚动监听 Mixin* 用于自动处理 custom-navbar 组件的滚动事件传递* * 使用方法:* 1. 在页面中引入此 mixin* 2. 确保 custom-navbar 组件有 ref="customNavbar"(默认)或自定义 ref* 3. 自动处理滚动事件传递* * 配置选项:* - scrollRefs: 需要传递滚动事件的组件 ref 数组,默认为 ['customNavbar']* * 使用示例:* * // 基础用法(使用默认 ref="customNavbar")* export default {*   mixins: [PageScrollMixin],*   // ... 其他配置* }* * // 自定义 ref 名称* export default {*   mixins: [PageScrollMixin],*   scrollRefs: ['myNavbar'], // 自定义 ref 名称*   // ... 其他配置* }* * // 多个组件* export default {*   mixins: [PageScrollMixin],*   scrollRefs: ['customNavbar', 'floatingButton'], // 多个组件*   // ... 其他配置* }*/export default {data() {return {// 默认的滚动组件 ref 列表scrollRefs: this.$options.scrollRefs || ['customNavbar']};},// 页面生命周期onPageScroll(e) {// 自动将页面滚动事件传递给所有配置的组件this.scrollRefs.forEach(refName => {if (this.$refs[refName] && typeof this.$refs[refName].handlePageScroll === 'function') {this.$refs[refName].handlePageScroll(e);}});}
};
<template><view><!-- 填充区,避免内容被导航栏遮挡 --><view class="navbar-placeholder" :style="{ height: navBarHeight + 'px' }"></view><!-- 自定义导航栏 --><view class="custom-navbar" :class="{ 'navbar-scrolled': isScrolled }":style="{ paddingTop: statusBarHeight + 'px', height: navBarHeight + 'px',backgroundColor: isScrolled ? backgroundColor : 'transparent'}"><view class="navbar-left" @click="handleBack" :style="{ height: capsuleHeight + 'px', lineHeight: capsuleHeight + 'px' }"><image :src="backIcon" mode="aspectFit" class="back-icon"></image></view><view class="navbar-title" :style="{ height: capsuleHeight + 'px', lineHeight: capsuleHeight + 'px' }">{{ title }}</view><view class="navbar-right" :style="{ height: capsuleHeight + 'px', lineHeight: capsuleHeight + 'px' }"><slot name="right"></slot></view></view></view>
</template><script>
import CommonEnum from "../../enum/common";export default {name: 'CustomNavbar',props: {title: {type: String,default: ''},backIcon: {type: String,default: CommonEnum.BACK_BUTTON},showBack: {type: Boolean,default: true},// 新增:滚动相关配置backgroundColor: {type: String,default: CommonEnum.BASE_COLOR // 滚动时的背景色,使用基调颜色},scrollThreshold: {type: Number,default: 20 // 滚动阈值,超过此值开始变色},enableScrollEffect: {type: Boolean,default: true // 是否启用滚动效果}},data() {return {statusBarHeight: 0,navBarHeight: 0,menuButtonInfo: null,capsuleHeight: 0,// 新增:滚动状态isScrolled: false,scrollTop: 0,lastScrollTop: 0}},mounted() {this.getSystemInfo();},methods: {getSystemInfo() {// 获取系统信息const systemInfo = uni.getSystemInfoSync();// 获取状态栏高度this.statusBarHeight = systemInfo.statusBarHeight;// 获取胶囊按钮信息this.menuButtonInfo = uni.getMenuButtonBoundingClientRect();// 计算胶囊高度this.capsuleHeight = this.menuButtonInfo.height;// 计算导航栏高度(胶囊底部到状态栏顶部的距离)this.navBarHeight = this.menuButtonInfo.bottom + 8;},handleBack() {if (this.showBack) {// 先触发自定义事件,让父组件有机会处理this.$emit('back');// 自动执行返回逻辑uni.navigateBack({delta: 1});}},// 新增:处理页面滚动(供父组件调用)handlePageScroll(e) {if (!this.enableScrollEffect) return;this.scrollTop = e.scrollTop;// 判断是否超过滚动阈值if (this.scrollTop > this.scrollThreshold) {if (!this.isScrolled) {this.isScrolled = true;this.$emit('scroll-change', { isScrolled: true, scrollTop: this.scrollTop });}} else {if (this.isScrolled) {this.isScrolled = false;this.$emit('scroll-change', { isScrolled: false, scrollTop: this.scrollTop });}}// 触发滚动事件,让父组件可以获取滚动信息this.$emit('scroll', {scrollTop: this.scrollTop,isScrolled: this.isScrolled});},// 新增:手动设置滚动状态(供父组件调用)setScrollState(scrollTop) {if (!this.enableScrollEffect) return;this.scrollTop = scrollTop;this.isScrolled = scrollTop > this.scrollThreshold;}}
}
</script><style lang="scss" scoped>
/* 填充区样式 */
.navbar-placeholder {width: 100%;background-color: transparent;
}/* 自定义导航栏样式 */
.custom-navbar {position: fixed;top: 0;left: 0;right: 0;z-index: 999;padding-top: 0;background-color: transparent;display: flex;align-items: center;justify-content: space-between;padding-left: 30rpx;padding-right: 30rpx;box-sizing: border-box;transition: background-color 0.3s ease; /* 添加过渡动画 */
}/* 滚动状态样式 */
.navbar-scrolled {box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1); /* 滚动时添加阴影 */
}.navbar-left {display: flex;align-items: center;justify-content: center;width: 60rpx;.back-icon {width: 56rpx;height: 56rpx;}
}.navbar-title {font-size: 36rpx;font-weight: bold;color: #695347;flex: 1;text-align: center;display: flex;align-items: center;justify-content: center;
}.navbar-right {width: 60rpx;display: flex;align-items: center;justify-content: center;
}
</style>
<template><view class="page"><custom-navbarref="customNavbar"title="基础页面"/><tile-grid/><view class="header" :style="{ backgroundColor: CommonEnum.BASE_COLOR }"><!-- 状态展示 --><status-displayv-if="loading"type="loading"loading-text="加载中..."/><!-- 页面内容将在这里添加 --></view></view>
</template><script>
import CommonEnum from "../../enum/common";
import StatusDisplay from "../../components/status-display/status-display.vue";export default {components: {StatusDisplay},data() {return {CommonEnum,loading: false}},onLoad() {// 页面加载时获取数据this.loadPageData()},methods: {// 加载页面数据async loadPageData() {this.loading = truetry {// TODO: 调用页面数据API// const response = await getPageData()// 模拟加载setTimeout(() => {this.loading = false}, 1000)} catch (error) {console.error('获取页面数据失败:', error)this.loading = false}}}
}
</script><style lang="scss" scoped>
.page {background: #F5F0E7;
}
.header {width: 100%;min-height: 100vh;display: flex;align-items: flex-start;flex-direction: column;padding: 0 15rpx;padding-bottom: 40rpx;
}
</style>

颜色是在枚举中是 #FFFFFF
图片都是 网络地址

雀语文章地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/92665.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/92665.shtml
英文地址,请注明出处:http://en.pswp.cn/web/92665.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自有域名功能详解——安全可控的企业级访问方案

ZeroNews 推出自有域名穿透功能&#xff0c;支持用户将已备案域名与内网服务绑定&#xff0c;实现专业级访问控制。本文将系统解析其核心能力与操作逻辑。功能价值1. 所有权掌控使用企业自有域名而非第三方子域名&#xff0c;强化品牌一致性及管理权限。2. 安全合规强制 TLS 加…

Python驱动的无人机多光谱-点云融合技术在生态三维建模与碳储量/生物量/LULC估算中的全流程实战

随着生态学、林学、地理信息科学等多个学科对“结构—功能”一体化研究的共同推进&#xff0c;无人机多光谱与结构光摄影测量&#xff08;SfM&#xff09;技术已经从早期实验室验证阶段&#xff0c;走向区域尺度精细生态监测与资源清查的主流工具。过去十年&#xff0c;厘米级空…

JDY-31蓝牙SPP串口透传模块

一、产品简介与应用 JDY-31蓝牙基于蓝牙3.0 SPP设计&#xff0c;这样可以支持Windows、Linux、android数据透传&#xff0c; 工作频段2.4GHZ&#xff0c;调制方式GFSK&#xff0c;最大发射功率8db&#xff0c;最大发射距离30米&#xff0c;支持用户通过 AT命令修改设备名、波特…

模块--继电器

继电器模块详解 继电器,是一种常见的电控置装置,其应用几乎无处不在。在家庭生活中,继电器被广泛应用于照明系统,电视机,空调等电器设备的控制,在工业领域,它们用于控制电机,泵站,生产等高功率设备的运行;继电器还在通信网络,交通系统以及医疗设备中发挥着重要作用。…

Error: error:0308010C:digital envelope routines::unsupported at new Hash

1.报错 这个错误通常与 Node.js 的版本有关。从报错信息中可以看到&#xff0c;使用的 Node 版本是 v22.2.0。 该错误是因为 Node.js v17 及以上版本使用了 OpenSSL 3.0&#xff0c;而一些旧的加密算法或方式在 OpenSSL 3.0 中不再支持。 在项目中&#xff0c;通常是因为 webpa…

OpenAI开发者平台快速入门与API实践指南

OpenAI开发者平台快速入门与API实践指南 一、平台简介 OpenAI开发者平台为开发者提供了强大的人工智能API接口&#xff0c;能够在短时间内实现文本生成、图像识别、音频处理等多种AI能力。本文将详细介绍如何快速上手&#xff0c;发起API请求&#xff0c;并讨论模型选型、功能…

从 GPT‑2 到 gpt‑oss:解析架构的迭代

From GPT-2 to gpt-oss: Analyzing the Architectural Advances 原文 https://magazine.sebastianraschka.com/p/from-gpt-2-to-gpt-oss-analyzing-the OpenAI 本周刚发布了两款新的开放权重的大语言模型&#xff1a;gpt-oss-120b 和 gpt-oss-20b&#xff0c;这是自 2019 年 GP…

一周学会Matplotlib3 Python 数据可视化-线条 (Line)

锋哥原创的Matplotlib3 Python数据可视化视频教程&#xff1a; https://www.bilibili.com/video/BV1UhtuzcEqX/ 课程介绍 本课程讲解利用python进行数据可视化 科研绘图-Matplotlib&#xff0c;学习Matplotlib图形参数基本设置&#xff0c;绘图参数及主要函数&#xff0c;以及…

09-netty基础-手写rpc-原理-01

netty系列文章&#xff1a; 01-netty基础-socket02-netty基础-java四种IO模型03-netty基础-多路复用select、poll、epoll04-netty基础-Reactor三种模型05-netty基础-ByteBuf数据结构06-netty基础-编码解码07-netty基础-自定义编解码器08-netty基础-自定义序列化和反序列化09-n…

Windows 小知识:Winodws 文件与文件夹名不区分大小写

专栏导航 上一篇&#xff1a;Windows 编程辅助技能&#xff1a;速览定义 回到目录 下一篇&#xff1a;无 本节前言 本节来分享一个小的知识点&#xff0c;具体地&#xff0c;我们在下面来细说。 一. Windows 系统的文件与文件夹的名字&#xff0c;不区分大小写 请大家…

嵌套-列表存储字典,字典存储列表,字典存储字典

字典存储列表aliens []for alien in range(10):new_alien {"id": alien, "color": "green", "speed": "slow" , "points": 20}aliens.append(new_alien)for alien in aliens[:5]:print(alien) print("...&…

个人笔记Mybatis2

4.配置解析4.1核心配置文件mybatis-config.xmlMyBatis配置包含对MyBatis行为方式有显著影响的设置和属性在 MyBatis 中有两种类型的事务管理器 (也就是 type"[JDBC|MANAGED]”configuration(配置) properties(属性) settings(设置) typeAliases(类型别名) typeHandlers(类…

使用 Maxwell 和 RabbitMQ 监控 Mysql Flowable 表变更

为什么需要监控数据库变化&#xff1f;当 Flowable 表中的数据发生变化&#xff08;例如插入新任务、更新状态或删除记录&#xff09;&#xff0c;我们可能需要触发其他操作&#xff0c;比如通知用户、更新仪表盘或启动新流程。Maxwell 可以读取 MySQL 的二进制日志&#xff08…

MySQL面试题及详细答案 155道(041-060)

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

mysql_mcp_server_pro源码部署及启动报错新手指南:让智能体长出手来直接获取到最底层的数据

文章目录 源码部署 1.克隆项目地址 2.创建虚拟环境 3.激活环境 4.进入项目目录下 5.安装依赖 6.进入到src目录 7.在当前目录下,新建一个.env文件 8.配置数据库信息 9.启动项目 10.启动权限管理启动项目 启动报错了: 问题现象与直接原因 解决方案与操作步骤 方案1:允许忽略未定…

jupyter服务器创建账户加映射对外账户地址

文章目录一、创建test1-test10用户&#xff08;跳过已存在的test3&#xff09;二、检查必要组件是否安装解决方法&#xff1a;用紧凑格式避免换行解析错误核心修复说明&#xff1a;使用方法&#xff1a;以下是根据需求生成的命令、检查脚本及启动脚本&#xff0c;按步骤执行即可…

DDR中的POD与ODT

一、POD&#xff08;Pseudo Open Drain&#xff09;技术1. 定义与工作原理POD&#xff08;伪开漏&#xff09; 是DDR4/LPDDR4引入的电压标准与驱动架构&#xff0c;替代传统的SSTL&#xff08;Stub Series Terminated Logic&#xff09;。其核心特征是将上拉电源从VDDQ改为VTT&…

企业架构之导论(1)

一、企业架构是什么 企业架构是对企业业务、数据、应用、技术四大核心领域及其相互关系的系统化描述与设计框架。它像一张“城市蓝图”,确保业务战略能精准映射到IT落地: 本质:是连接业务战略(做什么)与技术执行(怎么做)的结构化方法论。 核心组件: 业务架构:定义业…

实战:在已有K8S集群如何新增和删除Node节点

本篇文章将分享一下如何在已有集群添加新节点和删除现有节点1 新增节点到K8S集群新增节点可以分为准备节点、配置节点和将其加入集群三步。1.1 准备新节点准备一个相同操作系统的主机作为新节点。参考以前部署的文章&#xff1a;实战部署k8s 1.28版本集群&#xff0c;跟着操作到…

C++ 黑马 内存分配模型

一, 内存分配模型内存总共有四个分区1 代码区 主要用来存储二进制代码&#xff0c;由操作系统进行管理2 栈区 由编译器自己进行释放和分配&#xff0c;例如函数的传递的参数&#xff0c;局部变量&#xff0c;const修饰的局部常量等等....3 堆区 由程序员自己分配和释放&am…