vue3uniapp实现自定义拱形底部导航栏,解决首次闪烁问题
前言:
我最初在网上翻阅查找了很多方法,发现大家都是说在page.json中tabbar中添加:"custom": true,即可解决首次闪烁的问题,可是添加了我这边还是会闪烁,因此我这边改变了思路,使用了虚拟页面来解决此问题。
效果图:

一:编写
1. 在page.json中写一个初始页面,pages中的第一个对象是默认展示第一个页面,所以一定要在写一个。
"pages": [{"name": "index","path": "pages/index/index","style":{"navigationStyle":"custom"}},
2.新建index文件

3.编写index文件,因为我有三个页面,底部会有三个选项,每一个组件对应一个页面,Tabbr是我自定义的底部导航栏
<view><view><view v-if="pageStatus[0]" class="page__container" :style="pageContainerStyle(0)"><scroll-view class="scroll-view" scroll-y><BasicPage /></scroll-view></view><view v-if="pageStatus[1]" class="page__container" :style="pageContainerStyle(1)"><scroll-view class="scroll-view" scroll-y><InquiriesPage /></scroll-view></view><view v-if="pageStatus[2]" class="page__container" :style="pageContainerStyle(2)"><scroll-view class="scroll-view" scroll-y><user /></scroll-view></view></view>//自定义底部组件,后面会讲怎么写<Tabbr :current-page="0" @change="change"></Tabbr></view>
4.编写自定义导航栏,可以直接复制,修改路径为自己文件路径
<template><view class="tabbar-home"><!-- 拱形区域 --><view class="arched"></view><view class="arched-bg"></view><!-- 盒子 --><view class="tabbar-container"><view class="tabbar-item" v-for="(item, index) in tabbarList" :class="[item.centerItem ? ' center-item' : '']" @click="changeItem(item)"><view class="item-top"><image :src="currentItem == item.id ? item.selectIcon : item.icon"></image></view><view class="item-bottom" :class="[currentItem == item.id ? 'item-active' : '']"><text>{{ item.text }}</text></view></view></view></view>
</template>
<script setup>
import { defineProps, onMounted, ref } from 'vue'
const props = defineProps({currentPage: {type: Number,default: 0,},
})
const currentItem = ref(0)
const tabbarList = ref([{id: 0,path: '/pages/home/index',icon: '/static/images/tabBar/unhome.png',selectIcon: '/static/images/tabBar/homeSelect.png',text: '首页',centerItem: false,},{id: 1,path: '/pages/detail/index',icon: '/static/images/tabBar/unInquiries.png',selectIcon: '/static/images/tabBar/Inquiries.png',text: '问询',centerItem: true,},{id: 2,path: '/pages/user/index',icon: '/static/images/tabBar/unhome.png',selectIcon: '/static/images/tabBar/homeSelect.png',text: '我的',centerItem: false,},
])
const emit = defineEmits(['change'])
function changeItem(item) {currentItem.value = item.idemit('change', item)// uni.switchTab({// url: item.path,// })
}onMounted(() => {currentItem.value = props.currentPage// 非微信小程序需隐藏原生tabBar(微信小程序已通过"custom": true配置项隐藏原生tabbar)if (process.env.VUE_APP_PLATFORM != 'mp-weixin') {uni.hideTabBar()}
})
</script><style lang="scss" scoped>
.tabbar-home {z-index: 20090;height: 100rpx;position: fixed;left: 0;bottom: 0;box-shadow: 0rpx 0rpx 30rpx 0rpx rgba(0, 0, 0, 0.07);width: 100%;box-sizing: content-box;padding-bottom: env(safe-area-inset-bottom) !important;
}
view {padding: 0;margin: 0;box-sizing: border-box;
}.tabbar-container {position: absolute;bottom: 0rpx;left: 50%;transform: translateX(-50%);width: 100%;/* box-shadow: 0 0 5px #8d6c36; */display: flex;align-items: center;justify-content: space-around;padding: 5rpx 0;color: #8d6c36;height: 100%;padding-bottom: env(safe-area-inset-bottom) !important;box-shadow: 0rpx 0rpx 30rpx 0rpx rgba(0, 0, 0, 0.07);background-color: rgba(255, 255, 255, 1);z-index: inherit;
}.tabbar-container .tabbar-item {width: 20%;height: 80rpx;display: flex;flex-direction: column;justify-content: center;align-items: center;text-align: center;
}.tabbar-container .item-active {color: #01beff;
}.tabbar-container .center-item {display: block;position: relative;margin-top: 20rpx;
}.tabbar-container .tabbar-item .item-top {width: 70rpx;height: 70rpx;padding: 10rpx;background: #ffffff;
}.tabbar-container .center-item .item-top {flex-shrink: 0;width: 100%;height: 140rpx;padding: 20rpx;position: absolute;top: -70rpx;/* left: calc(50% - 50rpx); */border-radius: 50%;/* box-shadow: 0 0 5px #999; */// background-color: #f3d9a6;
}.tabbar-container .tabbar-item .item-top image {width: 40rpx;height: 40rpx;
}.tabbar-container .center-item .item-top image {width: 70rpx;height: 70rpx;
}.tabbar-container .tabbar-item .item-bottom {font-size: 28rpx;width: 100%;
}.tabbar-container .center-item .item-bottom {position: absolute;bottom: 0;
}
.arched {width: 120rpx;height: 120rpx;left: 50%;top: -42rpx;position: absolute;transform: translateX(-50%);border-radius: 50%;box-shadow: 0rpx 0rpx 30rpx 0rpx rgba(0, 0, 0, 0.07);background-color: rgba(255, 255, 255, 1);// border: 2rpx solid rgba(0, 0, 0, 0.1);z-index: 20089;
}
.arched-bg {position: absolute;left: 0;top: 0;width: 100%;height: 100%;z-index: 20089;background-color: rgba(255, 255, 255, 1);
}
</style>
5.在index文件中引入了自定义导航栏组件和各页面组件
<script setup lang="ts">
import Tabbr from '../Tabbar/index.vue'
import BasicPage from './sub-page/BasicPage/index.vue'
import InquiriesPage from './sub-page/Inquiries/index.vue'
import user from './sub-page/user/index.vue'
import { useOrderedChildren } from './sub-page/hooks'
const { children: items, addChild: addItem, removeChild: removeItem } = useOrderedChildren<any>()
const tabbarData = ref([{id: 0,path: '/pages/home/index',icon: '/static/images/tabBar/unhome.png',selectIcon: '/static/images/tabBar/homeSelect.png',text: '首页',centerItem: false,},{id: 1,path: '/pages/detail/index',icon: '/static/images/tabBar/unhome.png',selectIcon: '/static/images/tabBar/homeSelect.png',text: '问询',centerItem: true,},{id: 2,path: '/pages/user/index',icon: '/static/images/tabBar/unhome.png',selectIcon: '/static/images/tabBar/homeSelect.png',text: '我的',centerItem: false,},
])// 记录每个子页面的状态
const pageStatus = ref(Array.from({ length: tabbarData.value.length }, () => false))
const currentIndex = ref(0)
const change = (item: any) => {pageStatus.value = pageStatus.value.map(() => false)if (!pageStatus.value?.[item.id as number]) {pageStatus.value[item.id as number] = truecurrentIndex.value = item.idnextTick(() => {items.value?.[item.id as number]?.onLoad?.()})}
}
const pageContainerStyle = computed<(index: number) => any>(() => {console.log('currentIndex', currentIndex.value)return (index: number) => {const style: any = {}if (index !== currentIndex.value) {style.display = 'none'}return style}
})
onLoad((options) => {const index = Number(options?.index || 0)pageStatus.value[index] = truenextTick(() => {currentIndex.value = index})
})
</script>
6.对了提个醒,自定义导航栏组件要写在page文件中~
相关文章:
vue3uniapp实现自定义拱形底部导航栏,解决首次闪烁问题
前言: 我最初在网上翻阅查找了很多方法,发现大家都是说在page.json中tabbar中添加:"custom": true,即可解决首次闪烁的问题,可是添加了我这边还是会闪烁,因此我这边改变了思路,使用了虚拟页面来解…...
新需求编码如何注意低级错误代码
1. 日常开发常见错误问题 变量拷贝未修改变量定义的值刚开始是随意写的一个值,想等到上线的时候再改成正确的,但是上线的时候忘记改了程序常量配置的错误逻辑关系判断错误 常见的如都不为null、都不为空集合判断不为空逻辑取反了多个关系的 && …...
系统架构图设计(行业领域架构)
物联网 感知层:主要功能是感知和收集信息。感知层通过各种传感器、RFID标签等设备来识别物体、采集信息,并对这些信息进行初步处理。这一层的作用是实现对物理世界的感知和初步处理,为上层提供数据基础网络层:网络层负责处理和传输…...
windows 文件监控 c++ 11及以上版本可用
在该版本上稍微改了一下https://blog.csdn.net/weixin_50964512/article/details/125002563 #include<iostream> #include<string> #include<Windows.h> #include<list> #include<locale> using namespace std;class WatchFolder {HANDLE m_hFi…...
jsMind:炸裂项目,用JavaScript构建的思维导图库,GitHub上的热门开源项目
嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和工作学习方法 jsMind 是一个基于 JavaScript 的思维导图库,它利用 HTML5 Canvas 和 SVG 技术构建,可以轻松地在网页中嵌入和编辑思维导图。它以 …...
postman的脚本设置接口关联
pm常用的对象 变量基础知识 postman获取响应结果的脚本的编写 下面是购物场景存在接口信息的关联 登录进入---搜索商品---进入商品详情---加入购物车 资源在附件中,可以私聊单独发送 postman的SHA256加密 var CryptoJS require(crypto-js);// 需要加密的字符串 …...
【python】OpenCV—Tracking(10.3)—GOTURN
文章目录 1、功能描述2、模型介绍3、代码实现4、完整代码5、结果展示6、优缺点分析7、参考 1、功能描述 基于 Generic Object Tracking using Regression Networks 方法,实现单目标跟踪 2、模型介绍 (1)发表来自 Held D, Thrun S, Savarese…...
git pull遇到一个问题
shell request failed on channel 0 需要修改服务器配置[rootadmin ~]# cat /etc/security/limits.d/20-nproc.conf # Default limit for number of users processes to prevent # accidental fork bombs. # See rhbz #432903 for reasoning.* soft nproc 409…...
书生-第四期闯关:完成SSH连接与端口映射并运行hello_world.py
端口映射完成后,访问127.0.0.1:7860成功展示如下界面: 书生浦语大模型实战营 项目地址:https://github.com/InternLM/Tutorial/...
【CSS3】css开篇基础(5)
1.❤️❤️前言~🥳🎉🎉🎉 Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的…...
AI产品独立开发变现实战营,炒掉老板做自由职业赚大钱
课程背景 在经济下行和外部就业压力增大的背景下,为解决程序员的焦虑、失业和被裁员,我们开始了这门课程,课程基于3个真实已经盈利的商业项目,从0到1带你实践AI产品的设计、开发、运营和盈利模式的全流程开发。 课程特色 增加‘…...
【UE5.3 Cesium for Unreal】编译GlobePawn
目录 前言 效果 步骤 一、下载所需文件 二、下载CesiumForUnreal插件 三、处理下载的文件 四、修改代码 “CesiumForUnreal.uplugin”部分 “CesiumEditor.cpp”部分 “CesiumEditor.h”部分 “CesiumPanel.cpp”部分 “IonQuickAddPanel.cpp”部分 “IonQuickAd…...
idea连接数据库出现错误的解决方式
在使用idea连接数据库时,出现错误: The server has terminated the handshake. The protocol list option (enabledTLSProtocols) is set, this option might cause connection issues with some versions of MySQL. Consider removing the protocol li…...
数据分级分类工具:敏感数据识别中的AI智能化转型之路
背景 在现代数字化和信息化飞速发展的背景下,数据安全愈发成为企业与组织的重要课题,尤其是敏感数据的保护更是重中之重。敏感数据的泄露不仅会导致商业损失和法律责任,还会直接影响客户信任和企业声誉。为此,数据分级分类工具逐…...
乘云而上,OceanBase再越山峰
一座山峰都是一个挑战,每一次攀登都是一次超越。 商业数据库时代,面对国外数据库巨头这座大山,实现市场突破一直都是中国数据库产业多年夙愿,而OceanBase在金融核心系统等领域的攻坚克难,为产业突破交出一副令人信服的…...
设计模式4-工厂模式策略模式
目录 一 工厂模式 1.1 思想 1.2 案例 1.2.1 接口 1.2.2 实现类 1.2.3 工厂类 1.2.4 调用 二 策略模式 2.1 思想 2.2 案例 2.2.1 接口 2.2.2 实现类 2.2.3 策略类 2.2.4 调用 三 工厂模式策略模式 3.1 思想 3.2 案例 3.2.1 接口 3.2.2 实现类 3.2.3 定义F…...
使用Html5基本标签实现“时空电影网”案例步骤及详细代码
根据您的需求,我为您实现了对“时空电影网”电影节页面的美化。以下是详细的步骤: 设置一级标题“电影节”文字的颜色:将一级标题的颜色设置为深蓝色(#0000FF)。 <h1><font color"darkblue">电…...
Servlet 3.0 新特性全解
文章目录 Servlet3.0新特性全解Servlet 3.0 新增特性Servlet3.0的注解Servlet3.0的Web模块支持servlet3.0提供的异步处理提供异步原因实现异步原理配置servlet类成为异步的servlet类具体实现异步监听器改进的ServletAPI(上传文件) Servlet3.0新特性全解 tomcat 7以上的版本都支…...
VUE组件学习 | 五、v-for组件
v-for 指令基础知识 v-for 是 Vue.js 中的一个指令,用于基于源数据多次渲染元素或模板块。它类似于 JavaScript 中的 for 循环。 基本语法 <template><div><!-- 基本列表渲染 --><ul><li v-for"item in items" :key"i…...
uniapp写移动端,适配苹果手机底部导航栏,ios安全区问题,苹果手机遮挡底部信息,uview的u-action-sheet组件
手机上有很多组件,需要手机底部弹窗来做选择,picker选择器,select列选择器呀这些,在苹果手机上会被底部nav遮住 采用了好几种配置的方式,多多少少都不太行,还是采用css来做吧,但是css来写想让它生效&#x…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
