uniapp+vue3+ts --微信小程序tab导航可以上下滚动选中选项组件代码

uniapp+vue3+ts --微信小程序tab导航可以上下滚动选中选项组件代码

废话不多说,直接上代码。

组件代码:

<template><view class="scroll-tabs-container"><view class="radiusz bg-white pt-[10rpx] z-[999]" :class="{ 'scroll-tabs-sticky': sticky }"><u-tabsid="tabScrollTop"ref="tabScrollTop":list="tabs":current="active"@change="handleChangeTab":active-color="mainColor"bg-color="transparent":bar-width="90"font-size="24":gutter="26"name="title"></u-tabs></view><view class="content"><viewclass="px-[20rpx] pt-[20rpx] pb-[40rpx] w-full bg-white mb-[30rpx] box-border"v-for="(item, index) in tabs":key="item.id":class="'tabs' + index"><view v-if="item.is_show == 1"><view class="text-center"><text class="pr-[10rpx]">———</text>{{ item.title}}<text class="pl-[10rpx]">———</text></view><view class="mt-[40rpx]"><u-parse :html="item.description"></u-parse></view><view class="mt-[40rpx]"><apply-btn:customClass="customClass"btnText=""@popTrue="popTrue"></apply-btn></view></view></view></view></view>
</template><script lang="ts" setup>
const { proxy } = getCurrentInstance() as any
import cache from '@/utils/cache'
import { onShow } from '@dcloudio/uni-app'
/*** @description props参数说明* @property [number] scrollTop 外部传入的滚动条高度* @property [array] tabs tabs* @property [number] current 设置默认的tabIndex* @property [number]  stickyTop 固定定位的高度* @property [boolean] sticky 是否设置tab为固定定位* @property [number] itemOffsetTop 自定义滚动相隔间距,到达会切换tab* @property [object]  tabOptions tab的配置* @property [boolean] scrollTab 滚动时是否切换到指定的tab* @property [boolean] clickScroll 点击时是否滚动到相应位置* @property [number ] duration  滚动持续时长* @property [number] offsetTop 点击滚动到某一模块时的偏离值,每次点击滚动都会减去这个偏离值,这个值的单位是px,*/
const mainColor = ref(cache.get('btnCon').btn_bgColor)
const customClass = ref('m-auto') //按钮样式
const props = defineProps({value: {type: String || Number,default: null},scrollTab: {type: Boolean,default: true},clickScroll: {type: Boolean,default: true},scrollTop: {type: Number || String,default: null},tabs: {type: Array,default: () => [] as any[]},// 设置默认的tabIndexcurrent: {type: Number,default: 0},stickyTop: {type: String,default: null},// 是否将tab设为固定定位sticky: {type: Boolean,default: true},// 自定义间距 ,当 top小于等于这个距离的时候会切换tabitemOffsetTop: {type: Number,default: 60},tabOptions: {type: Object,default: () => ({})},duration: {type: Number,default: 300},offsetTop: {type: Number,default: 0}
})
const tabTopHeight = ref(0)
const active = ref(0)
const click = ref(false)
const timer = ref()
watch([() => props.scrollTop, () => active.value],([newScrollTop, newActive], [oldScrollTop, oldActive]) => {if (newScrollTop) {if (!click.value) {scrollToTab()}}if (newActive != oldActive) {nextTick(() => {scrollToElement()})}},{ immediate: true }
)onMounted(() => {getScrollTabTopHeight()
})
onShow(() => {isPopup.value = false
})
/*** @description: 跳转加盟申请页面* @param {*} isLogin 是否登陆* @return {*}*/
const popTrue = (isLogin: boolean) => {if (!isLogin) {isPopup.value = !isLogin} else {uni.navigateTo({url: linkUrl.value})}
}const getScrollTabTopHeight = async () => {// 获取tab的高度const query = (await createSelectorQueryForThis('#tabScrollTop', false)) as anyif (!query) returntabTopHeight.value = query.height
}const createSelectorQueryForThis = (selector: string, all: any) => {return new Promise((resolve) => {proxy.createSelectorQuery()[all ? 'selectAll' : 'select'](selector).boundingClientRect((rect: any) => {resolve(rect)}).exec()})
}const createSelectorQuery = (selector: any, all: any) => {return new Promise((resolve) => {proxy.createSelectorQuery()[all ? 'selectAll' : 'select'](selector).boundingClientRect((rect: any) => {resolve(rect)}).exec()})
}
const emit = defineEmits<{(event: 'onChange', index: number): void(event: 'input', active: any): void
}>()
const handleChangeTab = (index: any) => {active.value = indexclick.value = true
}
// 点击滑动到指定元素
const scrollToElement = async () => {if (!click.value) return falseconst tab = props.tabs[active.value]if (!tab) returnconst { scroll_id } = tab as anyif (!scroll_id) return falseclearTimeout(timer.value)const queryData = (await createSelectorQuery(`.${scroll_id}`, false)) as anyif (tabTopHeight.value === 0) await getScrollTabTopHeight()if (!queryData) {click.value = truereturn false}let scrollTop = props.scrollTop + queryData.top - props.offsetTopscrollTop -= tabTopHeight.value// 页面滚动函数uni.pageScrollTo({scrollTop,duration: props.duration,success: () => {timer.value = setTimeout(() => {click.value = false}, props.duration + 500)}})
}
const scrollToTab = async () => {if (!props.scrollTab && !click.value) return falseconst length = props.tabs.lengthlet allClass = ''for (let i = 0; i < length; i++) {const { scroll_id } = props.tabs[i] as anyallClass += i < length - 1 ? `.${scroll_id},` : `.${scroll_id}`}const queryData = (await createSelectorQuery(allClass, true)) as anyfor (let i = 0; i < queryData.length; i++) {if (queryData[i].top <= props.itemOffsetTop) {active.value = i}}
}
</script><style lang="scss" scoped>
.scroll-tabs-container {.status_bar {display: none;// height: var(--status-bar-height);}.scroll-tabs-sticky {z-index: 9999;overflow: hidden;-webkit-transform: translateZ(0);transform: translate3d(0, 0, 0);background: white;}
}
.radiusz {border-radius: 26rpx 26rpx 0 0;margin-top: -98rpx;border-bottom: 2px solid #eee;position: fixed;width: 100%;
}
</style>

页面调用代码:

<template><view class="bg-[#F3F4F6] w-full"><scroll-tabs:value="current":tabs="graphicIntroduction":tabOptions="{ label: 'title', activeColor: '#222', barColor: '#ff9f0f' }":offsetTop="180":scrollTop="scrollTop":sticky="true":itemOffsetTop="300 + statusBarHeight":clickScroll="clickScroll"></scroll-tabs></view></template><script lang="ts" setup>
import { getMiniNavigation } from '@/api/shop'
import { onLoad, onPageScroll } from '@dcloudio/uni-app'const bannerImg = ref('')
const graphicIntroduction = ref([]) as any
const current = ref(0) // tab默认索引const scrollTop = ref(0)
const clickScroll = ref(false)
const stickyTop = ref()
const statusBarHeight = ref()
onPageScroll((e: any) => {scrollTop.value = e.scrollTop
})onLoad(() => {getMiniNavigationData()// getHeight()uni.getSystemInfo({success: function (e: any) {stickyTop.value = e.statusBarHeight + 44 + 'px'statusBarHeight.value = e.statusBarHeight}})
})/*** @description: 获取首页轮播图和图文介绍* @return {*}*/
const getMiniNavigationData = async () => {const { data } = await getMiniNavigation({ type: 'plan' })bannerImg.value = data.bannerImgconst list = data.graphicIntroductionlist.forEach((item: any) => {if (item.is_show == 1) {graphicIntroduction.value.push(item)}})graphicIntroduction.value.forEach((item: any, index: number) => {item.scroll_id = `tabs${index}`})
}
</script>

效果图:
在这里插入图片描述

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

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

相关文章

文件包含漏洞长度截断

长度截断 文件漏洞的利用方式什么是长度截断通过实操理解00截断对版本要求更高一点&#xff0c;而长度截断则是利用了windows的系统漏洞&#xff0c;就是windows文件名&#xff08;就是文件名后缀之后&#xff09;之后如果有空格&#xff0c;或者是点都会被忽略掉&#xff0c;也…

Python tkinter (6) —— Listbox控件

Python的标准Tk GUI工具包的接口 tkinter系列文章 python tkinter窗口简单实现 Python tkinter (1) —— Label标签 Python tkinter (2) —— Button标签 Python tkinter (3) —— Entry标签 Python tkinter (4) —— Text控件 Python tkinter (5) 选项按钮与复选框 目录…

【并发编程】volatile原理

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程 ⛺️稳重求进&#xff0c;晒太阳 volatile原理实现是内存屏障&#xff0c;Memory Barrier 对volatile变量的写指令后会加入写屏障。对volatile变量的读指令前会加入读屏障 如何…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例5-2 JavaScript 获取HTML元素对象

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>JavaScript 获取 HTML 元素对象</title> </head><body> <input type"text" value"admin" /> <br> <input …

【深度学习:t-SNE 】T 分布随机邻域嵌入

【深度学习&#xff1a;t-SNE 】T 分布随机邻域嵌入 降低数据维度的目标什么是PCA和t-SNE&#xff0c;两者有什么区别或相似之处&#xff1f;主成分分析&#xff08;PCA&#xff09;t-分布式随机邻域嵌入&#xff08;t-SNE&#xff09; 在 MNIST 数据集上实现 PCA 和 t-SNE结论…

数据中心代理IP:最优性价比业务应用指南

数据中心代理IP在应对高速高并发的业务时&#xff0c;以独特的高速传输&#xff0c;游刃有余地应对多任务处理&#xff0c;适合于特定业务场景的高效加速。理性选用数据中心代理IP&#xff0c;可以为业务将迎来更加稳健和迅速的发展。今天&#xff0c;我们将揭示数据中心代理IP…

Python代码耗时统计

time模块 在代码执行前后各记录一个时间点&#xff0c;两个时间戳相减即程序运行耗时。这种方式虽然简单&#xff0c;但使用起来比较麻烦。 time.time() 函数返回的时间是相对于1970年1月1日的秒数 import timestart time.time() time.sleep(1) end time.time() print(f&…

flutter 搜索框实现,键盘搜索按钮,清空,防抖

import package:flutter/material.dart; import package:flutter_screenutil/flutter_screenutil.dart; import package:flutter_svg/svg.dart; import package:sy_project/config/app_colors.dart; import package:sy_project/core/assets.dart;/// 搜索textview class Custom…

【MIdjourne基础】 |MIdjourney基础参数全解析,各类辅助知识

文章目录 1 参数列表1.1 基础参数列表 2 基础参数详解2.1 模型版本选择2.2 模型出图模式选择2.3 基础生图参数2.3.1 --ar2.3.2 --stylize2.3.3 --no2.3.4 --chaos2.3.5 --quality2.3.6 --stop2.3.7 --hd2.3.8 --repeat 1 参数列表 1.1 基础参数列表 模型版本选择 目标参数作…

杂项基础知识

换行与回车 ASCII中的CR与LF CR&#xff08;Carriage Return&#xff09;&#xff0c;回车字符\r&#xff0c;控制字符&#xff0c;将光标移动到本行行首 LF&#xff08;Line Feed&#xff09;&#xff0c;换行字符\n&#xff0c;控制字符&#xff0c;将光标下移一行 ASCII…

【2024美赛实战】预测模型:灰色预测模型GM(1,1)

当题目数据少且无明显规律的时候&#xff0c;且要求进行短期预测的时候&#xff0c;或许可以考虑另一种预测方法——灰色预测模型GM(1,1)&#xff0c;虽然是个比较基础的预测模型&#xff0c;但在美赛O奖论文中登场次数也是比较多的。 一 预测问题的一般步骤 二 灰色预测模型…

Redis客户端之Redisson(三)Redisson分布式锁

一、背景&#xff1a; 高效的分布式锁设计应该包含以下几个要点&#xff1a; 1、互斥&#xff1a; 在分布式高并发的条件下&#xff0c;我们最需要保证&#xff0c;同一时刻只能有一个线程获得锁&#xff0c;这是最基本的一点 2、防止死锁&#xff1a; 在分布式高并发的条…

Cesium材质特效

文章目录 0.引言1.视频材质2.分辨率尺度3.云4.雾5.动态水面6.雷达扫描7.流动线8.电子围栏9.粒子烟花10.粒子火焰11.粒子天气 0.引言 现有的gis开发方向较流行的是webgis开发&#xff0c;其中Cesium是一款开源的WebGIS库&#xff0c;主要用于实时地球和空间数据的可视化和分析。…

动态规划算法题刷题笔记

首先看动态规划的三要素&#xff1a;重叠子问题、最优子结构和状态转移方程。 重叠子问题&#xff1a;存在大量的重复计算 最优子结构&#xff1a; 状态转移方程&#xff1a;当前状态转移成以前的状态 动态规划的解题步骤主要有&#xff1a; 确定 dp 数组以及下标的含义状…

苍穹外卖-前端部分(持续更新中)

d 第二种&#xff1a;cmd中输入 vue ui进入图形化界面选择npm,vue2进行创建 先将创建的Vue框架导入Vsocde开发工具 然后ctrshiftp 输入npm 点击serve将项目启动 下这种写法跨域会报错&#xff1a; 解决方法&#xff1a; \ 注意 这种用法&#xff1a;&#xff08;不是单引号…

Android Handler完全解读

一&#xff0c;概述 Handler在Android中比较基础&#xff0c;本文笔者将对此机制做一个完全解读。读者可简单参考上述类图与时序图&#xff0c;便于后续理解。 二&#xff0c;源码解读 1&#xff0c;主线程伊始 众所周知&#xff0c;通过Zygote的fork方式&#xff0c;新创建…

SSH客户端 Termius for Mac 中文激活版

Termius for Mac是一款强大的终端和SSH客户端&#xff0c;为开发人员、系统管理员和网络工程师提供了全面的远程访问和管理工具。 软件下载&#xff1a;Termius for Mac 中文激活版下载 无论您是在使用Mac、Windows还是Linux系统&#xff0c;Termius都能提供出色的功能和用户体…

静态代理IP该如何助力Facebook多账号注册运营?

在Facebook运营中&#xff0c;充分利用静态代理IP是多账号运营的关键一环。通过合理运用静态代理IP&#xff0c;不仅可以提高账号安全性&#xff0c;还能有效应对Facebook的算法和限制。以下是这些关键点&#xff0c;可以帮助你了解如何运用静态代理IP进行Facebook多账号运营&a…

基于springboo校园社团信息管理系统

摘要 随着高校规模的扩大和学生社团活动的日益丰富多彩&#xff0c;校园社团信息管理成为一个备受关注的问题。为了更有效地组织、管理和推动校园社团的发展&#xff0c;本文设计并实现了一套基于Spring Boot的校园社团信息管理系统。本系统以实现社团信息的集中管理和高效运营…

使用dockers-compose搭建开源监控和可视化工具

简介 Prometheus 和 Grafana 是两个常用的开源监控和可视化工具。 Prometheus 是一个用于存储和查询时间序列数据的系统。它提供了用于监控和报警的数据收集、存储、查询和图形化展示能力。Prometheus 使用拉模型&#xff08;pull model&#xff09;&#xff0c;通过 HTTP 协议…