当前位置: 首页 > news >正文

自定义tabs+索引列表,支持左右滑动切换

目录

    • 自定义tabs+索引列表,支持左右滑动切换
      • 创建scroll-x-tabs组件
      • 创建touch-list组件
      • 父组件使用

自定义tabs+索引列表,支持左右滑动切换

创建scroll-x-tabs组件

<view class="container"><scroll-viewclass="scroll-view"scroll-x="true":scroll-left="scrollLeft"scroll-with-animationshow-scrollbar="false"><viewv-for="(item, index) in list":key="`${item.dictValue}-${index}-${item.dictCode}`"class="scroll-item"@click="handleItemClick(index)":style="{color:(index === currentIndex ? computedActiveColor : computedColor) +' !important',}"><text>{{ item.dictLabel }}</text></view><!-- 指示条 --><viewv-if="list.length"class="indicator":style="{...indicatorStyle,background: lineColor,height: lineHeight,borderRadius: lineBorderRadius,}"></view></scroll-view></view>
props: {list: {type: Array,default: () => [],},color: {type: String,default: null,},activeColor: {type: String,default: null,},lineColor: {type: String,default: "rgba(0,0,0,0.5)",},lineHeight: {type: String,default: "6rpx",},lineBorderRadius: {type: String,default: "3rpx",},currentIndex: {type: Number,default: 0,},},data() {return {itemWidths: [], // 存储所有项的宽度containerWidth: 0, // 容器宽度scrollLeft: 0,indicatorLeft: 0,indicatorWidth: 60,};},computed: {...mapGetters(["appTheme"]),computedColor() {if (this.color) return this.color;return this.appTheme === "dark" ? "#999999" : "#333333";},computedActiveColor() {if (this.activeColor) return this.activeColor;return this.appTheme === "dark" ? "#ffffff" : "#000000";},indicatorStyle() {return {width: this.itemWidths[this.currentIndex]? `${this.itemWidths[this.currentIndex]}px`: "60px",transform: `translateX(${this.calculateIndicatorPosition()}px)`,};},},watch: {list: {handler() {this.$nextTick(() => {this.getItemWidths();});},deep: true,},currentIndex: {handler(newIndex) {this.$nextTick(() => {this.calculateScrollPosition();});},},},mounted() {this.getItemWidths();},methods: {getItemWidths(index = 0) {this.$nextTick(() => {const query = uni.createSelectorQuery().in(this);query.select(".scroll-view").boundingClientRect((containerData) => {if (containerData) {this.containerWidth = containerData.width;}}).exec();query.selectAll(".scroll-item").boundingClientRect((data) => {console.log("getItemWidths data", data);if (data) {// 保存所有项的宽度this.itemWidths = data.map((item) => item.width);// 计算当前项的位置this.calculateScrollPosition();}}).exec();});},calculateScrollPosition() {// 计算滚动位置,确保选中项在可视区域内let totalWidth = 0;for (let i = 0; i < this.currentIndex; i++) {totalWidth += this.itemWidths[i] || 120; // 如果没有宽度数据,使用默认值}// 计算选中项的中心位置const currentItemWidth = this.itemWidths[this.currentIndex] || 120;const targetPosition = totalWidth + currentItemWidth / 2;// 计算需要滚动的距离,使选中项居中this.scrollLeft = Math.max(0, targetPosition - this.containerWidth / 2);},calculateIndicatorPosition() {// 计算指示器位置let totalWidth = 0;for (let i = 0; i < this.currentIndex; i++) {totalWidth += this.itemWidths[i] || 120;}return totalWidth;},handleItemClick(index) {this.$emit("update:currentIndex", index);this.$emit("onHandleItemClick", index);this.$nextTick(() => {this.calculateScrollPosition();});},},
.container {width: 100%;padding: 10rpx 0;
}.scroll-view {width: 100%;white-space: nowrap;height: 80rpx;box-sizing: border-box;
}.scroll-item {display: inline-block;padding: 0 30rpx;height: 70rpx;line-height: 70rpx;text-align: center;font-size: 30rpx;color: #333;
}.indicator {transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

创建touch-list组件

<swiperclass="swiper-container":current="currentIndex"@change="handleSwiperChange":duration="300":style="{ height: swiperHeight }"><swiper-itemv-for="(item, index) in listLength":key="index"class="swiper-item"><view class="content" v-if="index === currentIndex"><slot></slot></view></swiper-item></swiper>
  props: {currentIndex: {type: Number,default: 0,},listLength: {type: Number,default: 0,},swiperHeight: {type: String,default: "500rpx",},},methods: {handleSwiperChange(e) {this.$emit("update:currentIndex", e.detail.current);this.$emit("onHandleSwiperChange", e.detail.current);},},
.swiper-container {width: 100%;
}.swiper-item {width: 100%;height: 100%;
}.content {width: 100%;height: 100%;overflow: scroll;
}

父组件使用

<scroll-x-tabs:list="exploreTypeDictList":currentIndex.sync="current":line-color="lineColor"></scroll-x-tabs><touch-list:list-length="exploreTypeDictList.length":currentIndex.sync="current":swiperHeight="swiperHeight"@onHandleSwiperChange="onHandleSwiperChange"
><view class="learn-grid" v-if="studyList.length"><!--列表内容--></view></touch-list>
http://www.dtcms.com/a/465849.html

相关文章:

  • 建设网站的必要与可行性制作企业网站需要注意的事项
  • MySQL查询优化实战从慢查询到高性能的索引重构策略
  • 官方网站建设报价wordpress 在线咨询
  • 从零实现JSON与图片文件上传功能
  • 第五部分:VTK高级功能模块(第140章 Accelerators模块 - 加速器支持类)
  • 头条站长平台电商网站开发实训软件
  • 库卡机械臂的转角系统以及固定轴和欧拉角的计算方式
  • 机器学习高级-Chapter 04-概率论与贝叶斯分类
  • 站点搜索编程零基础入门课程
  • 网站焦点图如何美观python做网站怎么样
  • SQL百题斩:从入门到精通,一站式解锁数据世界
  • TMC2240步进电机驱动芯片寄存器配置和电路设计
  • 高通被调查市占率将降,昂瑞微IPO推动射频芯片自主创新
  • SQL SERVER从专家到小白
  • 温州市企业网站制作网站升级建设中
  • 开源安全管理平台wazuh-暴力破解检测与响应
  • 视频网站用虚拟主机织梦网站标题被篡改
  • VBA即用型代码手册:创建一个新文档并保存html文件
  • 深圳模板网站多少钱音乐外链网站
  • Java 数学类详解:Math 类常用方法(abs/sqrt/random 等)一篇掌握
  • html 全角空格和半角空格
  • 网络协议之文件下载相关协议
  • 图数据库neo4j desktop2.0初探
  • 广州网站建设网络推广公司酒店旅游团购网站建设
  • 重庆镇海seo整站优化价格紫色个人网站模板
  • 有安全好用且稳定的共享网盘吗?
  • 网站空间是不是服务器南宁网站建设怎样建立一个好网站
  • 网站建设系统认证系统为什么建设银行的网站打不开
  • 并行传输如何重塑数据交换新格局
  • Maven用户设置文件(settings.xml)配置指南