vue实现一个tab组件(超出可滚动自动居中)

vue3标签页切换组件封装类似el-tabs vue3标签页切换组件开发 阅读详情

tabs.vue

<template>
  <div class="tabs">
    <div class="tabs__titles" ref="tabsTitlesRef">
    	<div class="tabs__titles-item"
         :class="{active : index === activeIndex}"
         @click="tabChange(item, index)"
         v-for="(item, index) in titles"
         :key="item.index">
         <div class="tabs__titles-item__line"></div>
         <slot v-if="$slots.title" name="title" :row="item"></slot>
         <div v-else class="tabs__titles-item__text">{{ item }}</div>
       </div>
     </div>
    <div class="tabs__content" :style="{'transform': translate}">
      <slot name="default"></slot>
    </div>
</div>
</template>

<script setup>
import {
  ref,
  useSlots,
  provide,
  defineProps,
} from 'vue';

// eslint-disable-next-line
const props = defineProps({
  modelValue: {
    default: '',
  },
});

const $slots = useSlots();
const titles = ref([]);
const tabsTitles = ref(null);
const activeIndex = ref(0);
const translate = ref('translateX(0%)');
const getTitles = (val) => {
  if (!$slots.title && typeof val !== 'string') {
    console.error('非自定义标题内容不允许传递对象类型');
  } else {
    titles.value.push(val);
  }
};
provide('getTitles', getTitles);
provide('activeKey', props.modelValue);

const scrollIntoView = (index) => {
  const { length } = document.querySelectorAll('.tabs__titles-item');
  const activeNodeNextNodeWidth = length === index + 1 ? 0 : document.querySelectorAll('.tabs__titles-item')[index + 1].offsetWidth;
  const width = window.innerWidth / 2 - activeNodeNextNodeWidth;

  let offset = 0;
  for (let i = length - 1; i > index + 1; i--) {
    offset += document.querySelectorAll('.tabs__titles-item')[i].offsetWidth;
  }

  if (offset > width) {
    document.querySelectorAll('.tabs__titles-item')[index].scrollIntoView({ inline: 'center' });
  } else {
    document.querySelectorAll('.tabs__titles-item')[length - 1].scrollIntoView({ inline: 'end' });
  }
};

const tabChange = (item, index) => {
  activeIndex.value = index;
  translate.value = `translateX(${-100 * index}%)`;
  scrollIntoView(index);
};
</script>

<style lang="scss">
.tabs {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.tabs__titles {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  background-color: #f8f8f8;
  flex-shrink: 0;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0 10px;
  scroll-behavior: smooth;
  .tabs__titles-item {
    width: auto!important;
    position: relative;
    flex: 1 0 auto;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 70px;
    padding: 0 10px;
  }
}
.tabs__titles-item.active {
  font-weight: 600;
  .tabs__titles-item__line {
    width: 40px;
    transition: width .3s ease;
  }
}
.tabs__titles-item__line {
  position: absolute;
  bottom: 15%;
  left: 50%;
  width: 0;
  height: 3px;
  background: -webkit-gradient(linear,left top,right top,from(#fa2c19),to(rgba(250,44,25,.15)));
  background: linear-gradient(90deg,#fa2c19 0%,rgba(250,44,25,.15) 100%);
  transform: translate(-50%);
  overflow: hidden;
}
.tabs__content {
  display: flex;
  flex-wrap: nowrap;
  transition-duration: 300ms;
}
.tabs__titles::-webkit-scrollbar {
    display: none;
    width: 0;
    background: transparent;
}
</style>

tabpane.vue

<template>
  <div class="tabpane">
    <slot></slot>
  </div>
</template>

<script setup>
import {
  defineProps,
  inject,
  onMounted,
} from 'vue';

// eslint-disable-next-line
const props = defineProps({
  title: [String, Object],
  paneKey: [String, Number],
});

const getTitles = inject('getTitles');

onMounted(() => {
  getTitles(props.title);
});

</script>

<style>
.tabpane {
  width: 100%;
  padding: 20px;
  flex-shrink: 0;
  overflow: auto;
  height: 100%;
}
</style>

使用

<template>
  <tabs v-model="state.tabValue">
    <tab-pane title="tab1">tab1内容</tab-pane>
    <tab-pane title="tab2">tab2内容</tab-pane>
    <tab-pane title="tab3">tab3内容</tab-pane>
  </tabs>
</template>
<script setup>
import { reactive } from 'vue';
const state = reactive({
	tabValue: '0'
})
</script>
实现Vue导航栏的滑动切换居中 这样,当导航栏超出容器宽度时,用户可以通过滑动来查看其他导航项,点击导航项会触发滑动到对应的索引,并且滑动时导航栏会自动对应高亮显示。根据实际需求和设计风格,你可以对样式和交互效果进行调整和定制化。的值,从而实现点击触发滑动到对应的索引。在上述代码中,导航栏的滑动效果通过设置。来允许导航栏超出部分可以水平滑动。导航栏的滑动容器使用。最后,在导航栏的样式中,设置。类来突出显示当前选中的项。计算出滑动的距离,并通过。通过给选中的导航项添加。属性应用于滑动容器。 阅读详情

相关推荐

微信小程序滚动Tab选项卡:左右可滑动切换

最终效果如上。问题: 1、tab标题总共8个,所以一屏无法全部显示。 2、tab内容区左右滑动切换时,tab标题随即做标记(active)。 3、当active的标题不在当前屏显示时,要使其能显示到当前屏中。 一、wxml结构 tab标题因一排八个,所以使用 scroll-view组件,使其可横向滚动。 tab内容可左右滑动切换,使用swiper组件实现 为了偷懒,

Sophie_U的博客 8万+

vue实现tabs点击自动滚动居中

template <ul ref='tabsRef'> <li class="all-style">全部</li> <li class="other-tab" @click="tabsOnclick($event)" v-for="item in datas">{{item}}</li> </ul> data部分 data{ return{ datas:[ '文学', '外国名著', '中国名著', '四大

qq_44472790的博客 6234

touchTab:适用于移动端滑动切换tab组件

touchTab 横向滑动tab组件 适用于移动端横向滑动tab组件使用,通过对外暴露相应的事件完成相应的切换逻辑 ###对外事件 @customEvent canTouchTabMove touchmove时触发,此时可处理滑动tab @customEvent clearTouchTabMove touchend时触发,可以滑动但不满足切换条件时触发 @customEvent canTouchTabSwitch touchend时触发,达到切换条件,触发切换事件 ###使用 var touchTabIns = new touchTab({ el: $( document.body ), //绑定事件的dom元素 id或jq对象 offsetX: 50 //触摸起止X偏移值,大于些值才会触发下拉事件 }); $.bind(touchTabIn

vue实现标签页切换/制作tab组件【详细】

在vue中实现标签页切换有如下2种方式: ① 使用动态组件 ② 使用路由

XL_0502的博客 5623

IGS精密星历高效获取与解析指南

本文详细介绍了IGS精密星历在高精度定位中的核心作用,对比了IGS Final、IGR和IGU等不同产品的精度与时效性差异。指南提供了从武汉大学、NASA CDDIS等数据中心高效下载数据的实战方法,并深入解析了SP3文件格式,帮助用户掌握精密星历的获取、解析与自动化处理技巧,以支持厘米级定位应用。

garlic的博客 839

【计算机图形学】Pov-Ray画的垃圾小车

效果: 代码: #include "colors.inc" #include "metals.inc" #include "glass.inc" //相机 //这个位置车子刚好落在草地上了 camera { location direction z*1.5 right x*image_width/image_height look_at

lishichengyan的博客 1749

**【组件】vue实现自定义tab栏下划线滚动过渡效果以及点击当前tab自动居中**

vue实现自定义tab栏下划线滚动过渡效果以及点击当前tab自动居中 小程序、前端交流群:609690978 先上效果图 组件代码: <template> <div v-if="list.length > 0" class="tabBlock"> <div @scroll="scroll" class="tabContent"> <div ref="tabContentScroll" class="tabContentScroll"&

你见过思念放过谁的博客 3112

Keil 5安装教程(C51与MDK共存)

目录前言MDK的安装C51的安装安装完成后的验证新建C51工程添加C51程序文件编译测试总结 前言 本篇文章将介绍嵌入式开发工具Keil 5的安装方法,并使MDK(Microcontroller Development Kit,开发stm32时会用到)和C51(51单片机C语言软件开发系统)共存。今后使用Keil 5可同时开发51单片机程序和ARM单片机程序,便于学习与从51到32的过渡。 注: 为防止商业纠纷,本篇文章不涉及文中软件的注册破解,请支持正版。 同时为了便于今后更深入的学习,本文不会介绍软件的

xushu_me的博客 6万+

记录--移动端 H5 Tab 如何滚动居中

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 移动端 H5 Tab 如何滚动居中 Tab 在 PC 端、移动端应用都上很常见,不过 Tab 在移动端 比 PC 端更复杂。为什么呢?移动端设备屏幕较窄,一般仅能展示 4 ~ 7 个 Item。考虑到用户体验,UI 往往要求程序员实现一个功能——点击 Item 后,Item 滚动到屏幕中央,拼多多的 Tab 就实现了这个功能。 ...

林恒的博客 1116

Python爬虫教程:抓取短视频平台数据(以抖音和快手为例)

为什么抓取短视频平台数据?内容分析:通过抓取短视频平台上的视频内容、标题、标签等数据,可以进行内容分类、趋势分析、话题分析等。情感分析:抓取视频的评论数据,并进行情感分析,帮助企业或组织了解公众的情绪反馈。用户行为分析市场监测:通过抓取特定关键词或标签下的视频数据,分析市场趋势,进行竞争对手分析。短视频平台数据类型:视频信息:包括视频标题、描述、标签、作者等。用户信息:包括用户的昵称、粉丝数、关注数等。互动数据评论数据:视频下的用户评论内容及用户信息。

2201_76125261的博客 3662

《用 AI 赋能医药科研创新》目录(持续更新)

本专栏旨在指导医学科研和药物研发人员运用AI技术提升研究效率。内容包括:利用AI分析文献、识别研究热点、自动生成研究草稿;在新药研发中,通过AI优化临床方案设计、受试者筛选等环节;介绍AI理论基础如大语言模型、提示词工程学及智能体技术发展历程。专栏采用5000-9000字的长文形式,系统讲解AI在医药研发各环节的应用方法,帮助研究者缩短周期、降低成本,推动医药研发进入智能化新阶段。

MD Code 499

Vue实现移动端的Tab标签页组件

移动端H5页面开发中,我们一般采用Vant组件库进行开发。有时候因为业务要求比较个性化,需要实现有自己产品风格的组件功能,这个时候在组件库的基础上进行修改是比较费时间的,反而自己动手实现组件功能,写样式比较快一些。 下面是Vant组件库的内容: 标签栏滚动 标签数量超过 5 个时,标签栏可以在水平方向上滚动,切换时会自动将当前标签居中。 <van-tabs> <van-tab v-for="index in 8" :title="'标签 ' + index"> 内容 {{

卡洛背心的博客 3055

融合双主干网络提升YOLOv8性能一种基于SOTA思想的目标检测改进

YOLOv8采用了单一的主干网络进行特征提取,通常是基于CSPDarknet作为骨干网络,在目标检测过程中通过不同的卷积层提取不同尺度的信息。虽然这种设计在大多数应用场景下表现出色,但在面对复杂背景、细节丰富的物体或小物体检测时,YOLOv8有时难以保持良好的精度。在本文中,我们提出了一种基于双主干网络的YOLOv8改进方案,通过结合先进的SOTA思想,全面提升了YOLOv8在目标检测任务中的表现。双主干网络架构。

博客 1153

vue组件之自定义tab切换组件(吸顶、滚动定位)等效果

123

weixin_45532305的博客 3777

6、基于集成学习技术的边坡稳定性预测及滑坡易发性研究

本研究基于集成学习技术对云阳县的边坡稳定性及滑坡易发性进行预测分析。通过比较SVM、RF、XGBoost和LR四种模型,发现集成学习模型在准确率和少数类识别方面表现更优。特征重要性分析表明剖面形状是影响边坡稳定性的关键因素。同时,引入基于定性分析的分区建模方法,构建父模型与子区域模型,提升了滑坡易发性制图的精度。研究成果为地质灾害的预防与管理提供了科学依据和技术支持。

peach的博客 126

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

UniApp 横向可滚动 Tab 组件开发详解

这是一个移动端横向滚动Tab组件,支持自动居中选中标签和高度自定义。核心功能包括:1) 横向滚动容器;2) 自动计算滚动位置使选中标签居中;3) 通过插槽支持自定义标签内容和样式;4) 双向绑定管理选中状态。组件采用Vue3编写,通过uni-app的scroll-view实现跨平台兼容,算法核心是精确计算标签中心点与容器宽度的关系,确保平滑滚动和边界处理。

weixin_45284808的博客 1039

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

一个vue滚动tab跟随切换的例子

分享一个我前几天做的移动端 tab滚动跟随的例子 随着滚动条的滚动,tab会对应进行切换 首先我们需要监听当前页面的滚动 mounted(){ //记录每个内容对用的dom数组 this.arrDom = document.getElementsByClassName("item-content"); window.addEventListener('scr...

weixin_43464837的博客 6370

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

vue3+ts实现Tab滚动居中

来实现水平滚动的效果。每个Tab元素设置了一些基本的样式,激活的Tab元素设置了加粗的字体。和当前激活的Tab元素的引用,然后计算出滚动的位置,使激活的Tab居中显示。最后,在样式中设置了容器的宽度为100%,并设置了。方法来初始化时居中显示当前激活的Tab。方法来将新的激活Tab居中显示。方法中,切换Tab时,会更新。方法来实现滚动效果。

温暖前端的博客 964

vue点击tab列表滚动对应位置,滚动列表也可切换tab

tab锚点

huanhuan03的博客 7015

vue实现tab切换和滚动锚点导航

tab切换 <template> <div> <div style="padding:15px;"> <div class="tabs-base"> <lzy-tabs size="large" @tabclick="tabChangeHander"> <lz...

liuzhongyu 5192

vue 横向滚动条 实现点击 元素滚动可视区域居中 效果

模拟vant的Tab标签页的标签滚动效果 效果:选中元素,在滚动条的可视区域里面自动居中,头尾两端不用居中 vant效果:https://youzan.github.io/vant/#/zh-CN/tab start() { /** * 1)先让选中的元素滚到可视区域的最左边 scrollLeft * 2)接着向右移动容器一半的距离 containWidth / 2 * 3)最后向左移动item一半的距离 offsetWi...

qq_40509733的博客 4131

vue实现table自动滚动

客户需求:右下角表格实现自动滚动本案例中没有使用任何第三方插件,全部使用vue中相关的js、css以及定时器方式实现。解决问题的第一步不是找代码,而是分析问题。列表自动滚动常见方式有两种(上下左右的滚动不赘述,只是方向的问题,本案例以向上自动滚动为例):(1)匀速滚动 (2)有间隔的平滑滚动。本案例先给出匀速滚动的方案。要匀速向上滚动,以我的经验,最容易想到的是用定时器实现,每隔一个时间差,列表向上移动一个像素(大于一个像素,可能会在视觉上给人卡顿掉帧的感觉),在时间够短的前提下,就会给人一种匀速向上的

芳草萋萋鹦鹉洲哦 5794

按钮居中vue_vue实现tab列表横向滚动时点击居中

ezgif.com-optimize.gifhtml结构{{ i.name }}内容css样式.topNav {height: 41rem / $model;background: #fff;display: flex;flex-flow:row nowrap;overflow: scroll;ul {display: inline-block;white-space: nowrap;li {di...

weixin_39902345的博客 1107

vue 组件水平滚动_可横向滑动的vue tab组件

示例前端使用技术:框架->vue组件>ly-tab一个用于移动端的可触摸滑动具有回弹效果的可复用Vue组件ly-tab 介绍地址ly-tab npm地址使用步骤1,引入包,定义成公共组件代码import LyTab from '../packages/tab'Vue.use(LyTab)2,页面调用,定义数据源,写事件代码//调用v-model="selectedId":items...

weixin_39913141的博客 2177
上一篇: js手写实现各种函数
下一篇: qiankun微应用的使用(vue)
kaiup
博客等级 码龄7年 32粉丝 37原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值