uniapp 实现滑动视图切换 顶部滚动导航栏
无论小程序的时候一般有这个功能,在页面处于首页时候,滑动视图,切换视图顶部滚动导航也跟着切换
1.想要实现这个功能就需要实现顶部导航栏,首先实现顶部滚导航栏 点击高亮颜色显示
模板代码
<scroll-view scroll-x="true" class="scroll-content" >
//滑动导航栏数组<view v-for="(item,index) in topBar" :key="index" class="scroll-item" ><text :class="index==topindex?'f-color-active':'f-color'" @click="addclick(index)" >{{item.name}}</text></view>
</scroll-view>
采用的是class样式绑定 ,写一份高亮样式,和普通样式,定义一个滑动默认高亮索引当,高亮索引等于当前的v-for点击的索引时候,高亮,
var topindex =ref(0);//默认第一个区域高亮索引//高亮方法var addclick=(index)=>{console.log("用户点击了第几个tabbar",index);// 索引改变用来判断当前样式是为否点击样式 这样就是topindex.value=index;};
css
/* 字体颜色 */
.f-color{color: #636263;
}/* 选中字体颜色 */
.f-color-active{color: #2979ff;
}
2.然后接下来实现滑动导航栏点击的时候内容区域的页面跟着切换,大概逻辑是一样的既然上面,通过高亮索引等于当前v-for循环的内容视图索引显示即可,但是要实现页面滑动,顶部导航栏也跟着滑动,所以下面的内容区域不能用view 而是使用swipier轮播器
滑动视图实现滑动效果(当然是关闭了自动切换那些属性的)
swpiper的current属性决定了当前滑动显示的视图区域
所以代码块就可以同v-for滚动导航的数据列表,来实现滚动导航栏在那个索引,内容显示那个索引 ,内容区域使用的是scrollview滚动视图,方便后期数据扩展来动态设置内容区域高度
<!-- swiper顶部的容器,让他可以随着选项卡切换而且切换 改变时候触发切换事件 current属性和数据的index刚好对应--><swiper :current="topindex" ><!-- 要跟着tab循环 所以数据也跟着循环 --><swiper-item v-for="(item,index) in topBar" :key="index" ><!-- 做滑底部刷新 @scrolltolower --><scroll-view :scroll-y="true" class="swiper-item" ><!--内容区域--></scroll-view> </swiper-item></swiper>
现在实现了滚动导航栏切换,内容区域切换,但是还没有实现内容区域滑动,上面的滚动条跟着变化所以,为swipper添加滑动事件,
<!-- viewindex是下方的视图id 滑动内容可以实现导航样式跟着改变到但是无法实现滑动导航区域滑动 --><scroll-view scroll-x="true" class="scroll-content" :scroll-into-view="viewindex" ><view v-for="(item,index) in topBar" :key="index" class="scroll-item" :id="'top'+index"><text :class="index==topindex?'f-color-active':'f-color'" @click="addclick(index)" >{{item.name}}</text></view></scroll-view>
<!-- swiper顶部的容器,让他可以随着选项卡切换而且切换 改变时候触发切换事件 current属性和数据的index刚好对应--><swiper @change="onChangeTab" :current="topindex" :style="'height:'+viewHeight+'px;'"><!-- 要跟着tab循环 所以数据也跟着循环 --><swiper-item v-for="(item,index) in topBar" :key="index" ><!-- 做滑底部刷新 @scrolltolower --><scroll-view :scroll-y="true" :style="'height:'+viewHeight+'px;'" class="swiper-item" ></scroll-view> </swiper-item></swiper>
修改后的js
var viewindex= ref(0)//高亮方法var addclick=(index)=>{console.log("用户点击了第几个tabbar",index);// 索引改变用来判断当前样式是为否点击样式topindex.value=index;console.log(topindex),// 视图跟顺点击改变viewindex="top"+index;};var onChangeTab=(e)=>{// 从wipper 滑动视图的detail拿到索引console.log("用户开始滑动页面",e.detail);// 把滑块索引传递实现滑动改变top 索引 用户滑动那个区域对应顶部导航也跟着滑动addclick(e.detail.current);};
滑动事件可以获取到当前元素参数,detail属性中可以知道当前滑动到第几个索引了,因为和滚动导航栏一样是循环的同样导航栏数据,所以索引位置能够皮蓬
这里我为滚动视图添加了:scroll-into-view="viewindex"属性,是因为当内容区域一直滑动,滚动导航栏可以会出现内容高亮的部分在显示可视外边,所以就要用该属性设置,内容区域的索引在哪,滚动导航的视图在哪,不然就出现高亮,但是高亮部分在滚动导航栏末尾
注意哦,这个属性定位视图范围是根据id来的,但是不能以数字开头,所以我的滚动导航栏的子视图id和js方法是做了拼接的
scroll-view对应的子视图
<view v-for="(item,index) in topBar" :key="index" class="scroll-item" :id="'top'+index">
和高亮方法做的拼接
viewindex="top"+index;
这样就实现了内容区域滑动,滚动导航栏滑动,但是还有个问题,当我
内容区域下滑到底刷新数据时(data=[…data,…apirespose.dataArrary]),
高度固定的到导致内容限制不完 善,所以要设置动态高度
所以内容区域的高度是动态变量
<swiper @change="onChangeTab" :current="topindex" :style="'height:'+viewHeight+'px;'"><!-- 要跟着tab循环 所以数据也跟着循环 --><swiper-item v-for="(item,index) in topBar" :key="index" ><!-- 做滑底部刷新 @scrolltolower --><scroll-view :scroll-y="true" :style="'height:'+viewHeight+'px;'" class="swiper-item" >
这里的viewHeight就是设置的变量,初始化为0,没有数据,等页面加载的时候根据手机设备高度来动态计算
var viewHeight=ref(0)
uniapp api获取设备信息
成功的回调函数中包含可使用高度
注意获取使用设备的可视化高度的时候要使用同步api 避免页面初始化,异步操作还没执行,应该先计算高度在初始化数据
计算可使用高度
//获取刘海以及状态栏区域const getDeviceHeight = () => {const res = uni.getSystemInfoSync();const system = res.platform;if( system ==='ios' ){return 44+res.statusBarHeight;}else if( system==='android' ){return 48+res.statusBarHeight;}else{return 0;}};
页面初始化时候开始计算高度:内容区域高度=可使用高度-滚动导航栏高度(rpx转px)-刘海/挖孔和状态栏高度
onLoad(()=>{console.log("=============程序开始加载,初始化=================");init();});//减去80
onReady(()=>{uni.getSystemInfo({success: (res) => {viewHeight.value = res.windowHeight - uni.upx2px(80)-getDeviceHeight();}})
})
这样就实现了所有内容,以下是完整代码,内容区域使用的是整合的组件,采用v-if判断是否应该在高亮时候显示
<template><view class="home"><!-- #ifdef MP-WEIXIN --><!-- 自定意的导航 --><view class="wx-nav"><view class="iconfont icon-fangdajing left"></view><text uni-title>小 猴 体 育</text><view class="iconfont icon-shouye right"></view></view><!-- 顶部滑动选项卡 --><!-- viewindex是下方的视图id 滑动内容可以实现导航样式跟着改变到但是无法实现滑动导航区域滑动 --><scroll-view scroll-x="true" class="scroll-content" :scroll-into-view="viewindex" ><view v-for="(item,index) in topBar" :key="index" class="scroll-item" :id="'top'+index"><text :class="index==topindex?'f-color-active':'f-color'" @click="addclick(index)" >{{item.name}}</text></view></scroll-view><!-- 导航过后是切换的栏 swper 考虑多方面使用封装为组件 --><view class="wx-content"><!-- swiper顶部的容器,让他可以随着选项卡切换而且切换 改变时候触发切换事件 current属性和数据的index刚好对应--><swiper @change="onChangeTab" :current="topindex" :style="'height:'+viewHeight+'px;'"><!-- 要跟着tab循环 所以数据也跟着循环 --><swiper-item v-for="(item,index) in topBar" :key="index" ><!-- 做滑底部刷新 @scrolltolower --><scroll-view :scroll-y="true" :style="'height:'+viewHeight+'px;'" class="swiper-item" ><block><!--推荐模块 轮框画图 urls 传递图片数组改变 --><indexSwipper greeting="Hola" message="customMessage" v-if="item.name=='推荐'" ></indexSwipper><ShopCard title="猜你喜欢" v-if="item.name=='推荐'" ></ShopCard><Recommend v-if="item.name=='推荐'" ></Recommend><CardList v-if="item.name=='推荐'" ></CardList><CardList v-if="item.name=='推荐'" ></CardList><CardList v-if="item.name=='推荐'" ></CardList><CardList v-if="item.name=='推荐'" ></CardList><!--推荐模块 轮框画图 urls 传递图片数组改变 --><ShopCard v-if="item.name=='运动户外'" title="体育户外"></ShopCard><index-banner url="../../static/img/banner1.jpg" v-if="item.name=='运动户外'"></index-banner ><index-icons v-if="item.name=='运动户外'"></index-icons><!-- 就是一个3X4的图片集合 --><!-- 传递imagelist的图片数组动态改变 这里写死--><index-imagelist v-if="item.name=='运动户外'"></index-imagelist><ShopCard title="热销爆品" v-if="item.name=='运动户外'"></ShopCard><index-hot v-if="item.name=='运动户外'"></index-hot><ShopCard title="推荐店铺" v-if="item.name=='运动户外'"></ShopCard><!--推荐模块 轮框画图 urls 传递图片数组改变 --><!-- <index-banner url="../../static/img/banner1.jpg"></index-banner> --><index-icons v-if="item.name=='服饰内衣'"></index-icons ><ShopCard title="推荐店铺" v-if="item.name=='服饰内衣'"></ShopCard><index-Shopper v-if="item.name=='服饰内衣'"></index-Shopper></block></scroll-view> </swiper-item></swiper></view></view>
</template><script setup>import ShopCard from '@/components/ShopCard/ShopCard.vue';
import Recommend from '@/components/Recommend/Recommend.vue';
import CardList from "@/components/CardList/CardList.vue";import {onLoad,onReady,onShow} from "@dcloudio/uni-app";import { reactive, ref,onMounted } from 'vue'var onChangeTab=(e)=>{// 从wipper 滑动视图的detail拿到索引console.log("用户开始滑动页面",e.detail);// 把滑块索引传递实现滑动改变top 索引 用户滑动那个区域对应顶部导航也跟着滑动addclick(e.detail.current);};//注意这里要弄成响应式 不然只会渲染一次 :scroll-into-view这个属性控制视图在几个var topindex=ref(0);// 滑动导航的索引,var viewindex=ref("top0")// swipper容器的默认高度var viewHeight = ref(0);//获取刘海以及状态栏区域的剩余空间var addclick=(index)=>{console.log("用户点击了第几个tabbar",index);// 索引改变用来判断当前样式是为否点击样式topindex.value=index;console.log(topindex),// 视图跟顺点击改变viewindex="top"+index;};var topBar=ref([]);var urls=ref([]);//获取刘海以及状态栏区域的空余显示区域const getDeviceHeight = () => {const res = uni.getSystemInfoSync();const system = res.platform;if( system ==='ios' ){return 44+res.statusBarHeight;}else if( system==='android' ){return 48+res.statusBarHeight;}else{return 0;}};var init=()=>{uni.request({url:"http://192.168.10.98:3000/api/index_list/data",success: (res) => {console.log("发送请求成功,这是返回值",res);var resdata=res.data.data;//响应体里面的数据 res.data是相应体一个code 还有个是dataconsole.log("得到的滑动标题栏的值",resdata.topBar)topBar.value=resdata.topBarconsole.log("得到各个模块的数据",resdata.data)},fail: (e) => {console.log(e)}})
};onLoad(()=>{console.log("=============程序开始加载,初始化=================");init();});
onReady(()=>{uni.getSystemInfo({success: (res) => {viewHeight.value = res.windowHeight - uni.upx2px(80)-getDeviceHeight();}})
})</script><style scoped lang="scss">
.home{.wx-nav{.iconfont{// iconfont字体进行更改大小font-size: 26px; }border-bottom: solid 1rpx #707070;background-color:#FFFFFF ;.left{margin-left: 30rpx;}.right{margin-right: 30rpx;}padding-bottom: 10rpx;margin-top: 80rpx;// 没写具体的高 差不多和底部导航栏一样·高合适height: 50rpx;width: 100%;display: flex;justify-content: space-between;text-align: center;}// 滑块.scroll-content{width: 100%;height: 90rpx;// 空白空间不换行white-space: nowrap;.scroll-item{padding: 10rpx 30rpx;display: inline-block;font-size: 32rpx;.f-color-active{padding: 15rpx 0;border-bottom: 6rpx solid #2979ff;}}}
}</style>
相关文章:

uniapp 实现滑动视图切换 顶部滚动导航栏
无论小程序的时候一般有这个功能,在页面处于首页时候,滑动视图,切换视图顶部滚动导航也跟着切换 1.想要实现这个功能就需要实现顶部导航栏,首先实现顶部滚导航栏 点击高亮颜色显示 模板代码 <scroll-view scroll-x"true" class"scroll-content" > …...
ArcGIS API for JavaScript 调用自定义地图模板总结
ArcGIS API for JavaScript 调用自定义地图模板总结 3.9版本4.24版本 3.9版本 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>Hello World</title><link rel"stylesheet" href&qu…...

QGraphicsView实现简易地图5『经纬网格』
前文链接:QGraphicsView实现简易地图4『局部加载-地图漫游』 由于GCJ02 Web 墨卡托投影 纬度并不随像素等分,且两极跨度较大,因此本次演示采用的经纬网等分逻辑为等分像素。同等像素跨度之间,两级纬度变化较小,越靠近赤…...

RestTemplate 请求转发异常 ERR_CONTENT_DECODING_FAILED 200 (OK)
#1 问题描述 在基于Spring Boot的项目中实现了请求转发(使用 RestTemplate 的 exchange 方法)的功能,忽然在前端报net::ERR_CONTENT_DECODING_FAILED 200 (OK)的错误,后端及上游系统日志均显示请求已完成。 #2 原因探寻 上述错…...
用python实现一个异或计算器
有这样一条需求:计算某个文件中的数组每一行元素的最后一个参数,异或输出。 因为元素比较多,十几行,通过人工去计算异或值非常困难。 而在线异或的计算器,也需要人为输入这些数值,每次计算一个最终结果需…...
Sketch打不开AI文件?转换方法在这里
1、对比设计软件 Sketch 与 AI 软件功能 Sketch 与 Illustrator 都是行业内优秀的矢量图形设计软件,各有千秋。Sketch 从 2010 年面世,专注 APP 界面设计,深受初学者与专业人士喜爱。Illustrator 拥有更悠久的历史,是处理复杂图标…...

小游戏扫雷实现教学(详解)
目录 【前言】 一、模块化程序设计(多文件编程)介绍 1.概述 2.传统编程的方式 3.模块化程序设计的方法 二、扫雷代码设计思路 三、扫雷代码设计 1.创建菜单函数 2.实现9x9扫雷 3.初始化棋盘 4.打印棋盘 5.随机布置雷的位置 6.排查雷的信息 7.回…...

04 mysql innodb record
前言 最近看到了 何登成 大佬的 "深入MySQL源码 -- Step By Step" 的 pdf 呵呵 似乎是找到了一些 方向 之前对于 mysql 方面的东西, 更多的仅仅是简单的使用[业务中的各种增删改查], 以及一些面试题的背诵 这里会参照 MySQL Internals Manual 来大致的看一下 i…...
Centos7安装Docker
0.安装Docker Docker 分为 CE 和 EE 两大版本。CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道…...

Vue中如何更好地封装组件?
子组件接受父组件传递的事件 1.子组件使用事件名"$emit(父组件中传递的事件名,想给父组件传递的参数(可选))" click"$emit(click)" 2.子组件使用 v-on"$listeners" 父组件: <template><div id"app"><myCo…...

C语言的链表的相关操作
本变博客源于自己想复习一下C语言,所以便自己动手复习了一下链表的相关操作。做个人记录使用。 main.c #include <stdio.h> #include "list.h"int main() {student *a;printf("hello world\n") ;printf("----初始化列表----------\…...
Python3中typing模块
Python类型注解是Python 3.5版本之后引入的新特性,它可以让开发者在函数、变量等声明时为其指定类型。typing模型能够声明类型,防止运行时出现参数和返回值类型不符合的问题。 ### 1. 基本类型注解 def hello(name: str) -> str:return (Hello, na…...
C语言自动抓取淘宝商品详情网页数据,实现轻松高效爬虫
你是否曾经遇到过需要大量获取网页上的数据,但手动复制粘贴又太过费时费力?那么这篇文章就是为你而写。今天我们将会详细讨论如何使用C语言实现自动抓取网页上的数据。本文将会从以下8个方面进行逐步分析讨论。 1. HTTP协议的基本原理 在开始之前&…...

数据结构---跳表
目录标题 为什么会有跳表跳表的原理跳表的模拟实现准备工作find函数insert函数erase函数 测试效率比较 为什么会有跳表 在前面的学习过程中我们学习过链表这个容器,这个容器在头部和尾部插入数据的时间复杂度为O(1),但是该容器存在一个缺陷就是不管数据…...
为什么Tomcat的NIO在读取body时要模拟阻塞?
文章首发地址 Tomcat的NIO完全可以以非阻塞方式处理IO,为什么在读取body部分时要模拟阻塞呢?在Tomcat的NIO读取HTTP请求时,为了保证请求的正确性和可靠性,需要模拟阻塞模式,这是因为servlet规范里定义了ServletInputSt…...
26 | 谷歌应用APP数据分析
基于kaggle公开数据集,对谷歌应用市场的APP情况进行数据探索和分析。 from kaggle: https://www.kaggle.com/lava18/google-play-store-apps 分析思路: 0、数据准备 1、数据概览 2、种类对Rating的影响 3、定价策略 4、因素相关性分析 5、用户评价 6、总结 0、数据准备 (…...

BFS 五香豆腐
题目描述 经过谢老师n次的教导,dfc终于觉悟了——过于腐败是不对的。但是dfc自身却无法改变自己,于是他找到了你,请求你的帮助。 dfc的内心可以看成是5*5个分区组成,每个分区都可以决定的的去向,0表示继续爱好腐败&…...

opencv实战项目 手势识别-手势控制键盘
手势识别是一种人机交互技术,通过识别人的手势动作,从而实现对计算机、智能手机、智能电视等设备的操作和控制。 1. opencv实现手部追踪(定位手部关键点) 2.opencv实战项目 实现手势跟踪并返回位置信息(封装调用&am…...

1.作用域
1.1局部作用域 局部作用域分为函数作用域和块作用域。 1.函数作用域: 在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。 总结: (1)函数内部声明的变量,在函数外部无法被访问 (2)函数的参数也是函数内部的局部变量 (3)不同函数…...
黑马B站八股文学习笔记
视频地址:https://www.yuque.com/linxun-bpyj0/linxun/vy91es9lyg7kbfnr 大纲 基础篇 基础篇要点:算法、数据结构、基础设计模式 1. 二分查找 要求 能够用自己语言描述二分查找算法能够手写二分查找代码能够解答一些变化后的考法 算法描述 前提&a…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...

GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...