vue3-scroll-more:横向滚动条-元素或页签过多滚动显示处理的组件

滚动条是一个非常常用的组件,或者说滚动是一个非常常见的交互模式,平常见的最多的可能就是纵向滚动了,可以用较小的空间浏览较多的内容。

但是也有很多场景是横向滚动的,我们可以通过向左向右按住鼠标中间的滚轮来操作,也可以通过按住键盘上面的shift键,然后滚动滚轮来操作。

大家可能都遇到过需要在页面上展示已打开页签的情况,这些页签一般横向排列,当页签打开过多的时候,就必然需要做一些处理来满足一个友好的交互,既能保证之前页签存在,又能快速访问所有页签,提供给用户方便又直观的操作效果。

如顶部图片所示,这就是今天我们要介绍的组件,帮你快速实现上面的需求。

使用方式

安装

根据不同的包管理器选择不同的安装方式

shell 复制代码
--npm
npm install vue3-scroll-more

--pnpm
pnpm install vue3-scroll-more

--yarn
yarn add vue3-scroll-more

--bun
bun install vue3-scroll-more

引入

全局引入

javascript 复制代码
import Vue3ScrollMore from 'vue3-scroll-more'
const app = createApp(App)
app.use(vue3TagInput)

局部引入

javascript 复制代码
import { Vue3ScrollMore } from 'vue3-scroll-more'

使用

在任意组件的任意地方使用vue3-scroll-more组件,默认插槽就是我们要显示的元素,可以根据自己具体的需求任意设置,跟列表差不多,需要传入data数据,它是一个数组,用来循环遍历显示我们的默认插槽的内容,并且这是一个作用域插槽,可以接收两个参数,数组的每一项item和索引index,然后就可以根据这两个参数做一些自定义的配置和操作

还有很多其他属性,不过只有data是必填的

html 复制代码
<template>
  <div class="tags-view-container">
    <vue3-scroll-more :data="list" :side-change="sideChange">
      <template v-slot="{ item, index }">
        <span class="tags-view-item" :class="currentIndex === index ? 'active' : ''" @click="setCurrentIndex(index)">
          {{ item }}
          <el-icon v-if="index !== 0" class="el-icon-close" title="关闭">
            <Close />
          </el-icon>
        </span>
      </template>
    </vue3-scroll-more>
  </div>
</template>

功能

滚动

如果没有占满宽度的话,那就默认正常展示

一旦内容过长,将自动出现滚动机制,并且不会出现滚动条,只需正常滚动鼠标滚轮即可,跟纵向滚动相同

按钮

除了使用鼠标滚动之外,还可以显示两侧按钮,使用鼠标单击来进行滚动操作

左右两侧各有一个图标按钮,指示可以滚动的方向,如果一侧滚动到头,那么相应图标的颜色就会变成灰色,还可以继续滚动的一侧图标会稍微颜色加深,当鼠标悬浮在可滚动的按钮上面时,颜色会更深一些以进行友好反馈

如果鼠标点击按住不放,还可以进行连续滚动,适合需要快速滚动的需求,而且速度也是可以调节的

数量

出现了滚动条,那么必然有一部分内容是处于隐藏状态的,我们也可以让它显示隐藏的元素的个数,个数的计算规则是只要露出的部分小于三分之二,或者说被隐藏的部分大于三分之一,那么就会被计算到隐藏的个数里面

条数的显示也能够设置最大值,比如大于99条时,最大只显示99

隐藏内容

如果我们想查看隐藏的内容也是可以的,不通过滚动也能够找到对应的元素进行交互,配置上对应的属性,即可在鼠标悬浮于按钮上的时候展示出被隐藏的内容

这样就能直观的看到被隐藏的部分,而不用滚动既有元素,隐藏部分的内容通过垂直的方式进行展示,可以设置最大高度,超过高度就变成了我们最熟悉的纵向滚动了

拖拽

我们也可以对元素进行拖拽,以调整它们的顺序,不光可以拖拽横向的元素向左右两边重新排布位置,隐藏内容区域也可以拖拽来重新排布上下的位置,而且左右两边的元素还能够拖拽到横向的区域进行放置,拖拽的规则是被拖拽的元素如果放置在悬浮元素的前半部分,那么就将拖拽的元素插入到悬浮元素的前面,如果被拖拽的元素放置在悬浮元素的后半部分,那么就将拖拽的元素插入到悬浮元素的后面,同理上下拖动的元素也是根据悬浮元素的上半部分和下半部分进行处理

中间部分拖拽:

两边部分拖拽:

两边往中间拖拽:

自动跳转

中间部分点击对应的元素可以设置高亮,并且视觉上易于识别,当我们点击两边隐藏内容中的元素时,也可以设置它的行为,如将所点击的元素自动滚动到视口中,并处于最右边,或者处于最中间等等

能够设置五种模式:

  1. 点击两边内容中的元素尽量显示在最左边,除非无法滚动
  2. 点击两边内容中的元素尽量显示在最右边,除非无法滚动
  3. 点击两边内容中的元素尽量显示在最中间,除非无法滚动
  4. 点击左边内容中的元素尽量显示在最左边,点击右边内容中的元素尽量显示在最右边,除非无法滚动
  5. 不产生滚动变化,不自动出现在视口中

简单演示两种

组件配置

属性

javascript 复制代码
// 组件数据, 基于数组渲染默认插槽
data: {
  type: Array,
  default: () => ([])
},
// 唯一标识, 用于给v-for绑定key
keySign: {
  type: String
},
// 两边列表的高度
sideHeight: {
  type: Number,
  default: 300
},
// 当滚动条出现或者消失的时候触发, 接收一个参数对象, options.type的show表示滚动显示或者hide表示滚动消失
sideChange: {
  type: Function,
  default: (options) => ({})
},
// 是否显示数量
showNum: {
  type: Boolean,
  default: true
},
// 显示数量的最大值
maxNum: {
  type: Number,
  default: 999
},
// 是否展示两边的按钮
showButton: {
  type: Boolean,
  default: true
},
// 是否展示隐藏的内容
showHidden: {
  type: Boolean,
  default: true
},
// 点击元素的时候自动跳转到视口区域
// left: 总是展示在最左边
// right: 总是展示在最右边
// center: 总是展示在最中间
// auto: 总是按照默认行为展示
// none: 什么都不做
autoJump: {
  type: String as PropType<'left' | 'right' | 'center' | 'auto' | 'none'>,
  default: 'none'
},
// 当鼠标长按两个按钮的时候滚动的速度
autoScrollRate: {
  type: Number,
  default: 10
},
// 元素是否可以拖动以进行重新排序
draggable: {
  type: Boolean,
  default: false
}

插槽

一般情况下,只需传入默认插槽即可,两边的内容会自动根据默认插槽进行渲染,不过也可以手动传入自定义的插槽内容

规则是:两边插槽都不传,都使用默认插槽,两边只传了一个,另一个使用传入的那个,都传了,使用各自的内容

javascript 复制代码
default(props: { item: any, index: number })
start(props: { item: any, index: number })
end(props: { item: any, index: number })

示例

html 复制代码
<script setup lang="ts">
import { ref } from 'vue';
import { Vue3ScrollMore } from 'vue3-scroll-more'

const list = ref(new Array(20).fill(0).map((_, ind) => ("菜单" + ind)))

function sideChange(option: any) {
  console.log(option)
}
const currentIndex = ref(0)
function setCurrentIndex(ind: number) {
  currentIndex.value = ind
}
</script>

<template>
  <div class="tags-view-container">
    <vue3-scroll-more :data="list" :side-change="sideChange">
      <template v-slot="{ item, index }">
        <span class="tags-view-item" :class="currentIndex === index ? 'active' : ''" @click="setCurrentIndex(index)">
          {{ item }}
          <el-icon v-if="index !== 0" class="el-icon-close" title="关闭">
            <Close />
          </el-icon>
        </span>
      </template>
    </vue3-scroll-more>
  </div>
</template>

<style lang="scss" scoped>
.tags-view-container {
  padding-bottom: 4px;
  border-bottom: 1px solid #d8dce5;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12), 0 0 3px 0 rgba(0, 0, 0, 0.04);

  .tags-view-item {
    display: inline-block;
    position: relative;
    cursor: pointer;
    height: 26px;
    line-height: 26px;
    border: 1px solid #d8dce5;
    color: #495060;
    background: #fff;
    padding: 0 8px;
    font-size: 12px;
    margin-left: 5px;
    margin-top: 4px;
    white-space: nowrap;

    &.active {
      background-color: #42b983;
      color: #fff;
      border-color: #42b983;

      &::before {
        content: "";
        background: #fff;
        display: inline-block;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        position: relative;
        margin-right: 2px;
      }
    }

    .el-icon-close {
      width: 16px;
      height: 16px;
      vertical-align: -2px;
      margin-left: 5px;
      margin-right: -5px;
    }
  }
}
</style>

通过这个组件,可以让我们横向滚动的场景在交互的时候显的更丰满,可发挥的空间也更充足

希望能够帮助到有类似需求场景的你


另有一个可视化设计页面、搭建系统的项目可以体验一下

【项目体验】

系统管理端地址www.lecen.top/manage

系统用户端地址www.liudaxianer.com/user

系统文档地址www.lnsstyp.com/web

相关推荐
代码搬运媛1 小时前
Claude 全栈开发专用 Rules 配置
前端
PedroQue991 小时前
uni-router v1.7.0重磅更新:守卫重定向自由掌控
前端·uni-app
Forever7_1 小时前
尤雨溪转发:Vue-tui 0.1 发布!Vue 终于杀进终端!
vue.js
逸铭1 小时前
Day 4:登录与 Token——桌面端怎么存密钥
前端·客户端
dkbnull1 小时前
Vue 虚拟 DOM Diff 算法与 key 机制原理
vue.js
溯朢1 小时前
TokUI 流式渲染的 SSE 全链路拆解
前端
京东云开发者1 小时前
京东 Oxygen xLLM 大模型推理引擎正式捐赠开放原子开源基金会,共建国产 AI Infra 生态
前端
Csvn1 小时前
LLM 一把梭:从 Swagger 文档到类型安全 API 请求,再也不手写接口
前端
DGT1 小时前
深入理解 JavaScript 闭包
前端