- 安装npm install vuescroll
- 页面使用
<vuescroll :ops="ops" ref="vs" @handle-scroll="handleScroll">
<!-- 需要滚动的内容 -->
</vuescroll>
- 部分ops参数
ops2: {
rail: {
background: 'transparent',
opacity: 1,
specifyBorderRadius: false,
gutterOfEnds: null, //轨道距 x 和 y 轴两端的距离
// gutterOfSide: '518px', //距离容器的距离 从下往上
keepShow: true, //是否即使 bar 不存在的情况下也保持显示
border: 'none' //边框
},
bar: {
size: '7px',
background: "#2E5BFF",
opacity: 1,
keepShow: true, //是否即使 bar 不存在的情况下也保持显示
},
},
- ops参数配置参考链接
- 结合scrollIntoView实现分页锚点跳转
// 所有属性参数
在JavaScript中,scrollIntoView()方法是DOM元素的原生方法,用于将元素滚动到视图中。以下是该方法可接收的所有属性参数说明:
behavior: 定义了滚动行为(平滑或者立即滚动)。可选值为 "auto"(默认,即立即滚动)和 "smooth"(平滑滚动)。例如:
element.scrollIntoView({ behavior: "smooth" });
block: 定义了垂直方向上如何对齐元素(块级元素),可选值为 "start"、"center"、"end" 和 "nearest"(默认)。例如:
element.scrollIntoView({ block: "start" }); // 对齐到视口顶部
inline: 定义了水平方向上如何对齐元素(内联元素),可选值为 "start"、"center"、"end" 和 "nearest"(默认)。例如:
element.scrollIntoView({ inline: "start" }); // 对齐到左边
inlineFragment: 一个布尔值,指示是否应该滚动到离指定元素最近的包含它的 fragment。默认为 false,即滚动到整个文档的顶部。该选项仅在使用 CSS Fragmentation API 时才有用。
scrollMode: 定义了模式,控制着一些额外的滚动行为。可选值为 "if-needed" 或 "always"(默认)。例如:
element.scrollIntoView({ scrollMode: "if-needed" }); // 只在必要时滚动
请注意,不同浏览器对于scrollIntoView()方法的支持和实现略有不同,有些选项可能无法在某些浏览器中使用或者表现不一致,具体细节可以参考MDN文档的相关说明。
最终实现一个分页横向滚动
<template>
<div class="box">
<div class="out">
<vuescroll :ops="ops" ref="vs" @handle-scroll="handleScroll">
<div class="wrapper">
<div class="content" :id="`scroll${index + 1}`" :ref="`scroll${index + 1}`" v-for="item, index in list"
:key="item.id">
{{ item.name }}</div>
</div>
</vuescroll>
</div>
<div class="block">
<el-pagination @current-change="handleCurrentChange" :current-page.sync="currentPage" :page-size="1"
layout="prev, pager, next, jumper" :total="list.length">
</el-pagination>
</div>
</div>
</template>
<script>
import vuescroll from "vuescroll";
export default {
data () {
return {
currentPage: 1,
list: [{ id: 1, name: 1 }, { id: 2, name: 22 }, { id: 3, name: 333 }, { id: 4, name: 4444 }, { id: 5, name: 55555 }, { id: 6, name: 666666 }],
ops: {
rail: {
background: 'transparent',
opacity: 1,
specifyBorderRadius: false,
gutterOfEnds: null, //轨道距 x 和 y 轴两端的距离
// gutterOfSide: '518px', //距离容器的距离
keepShow: true, //是否即使 bar 不存在的情况下也保持显示
border: 'none' //边框
},
bar: {
size: '7px',
background: "#2E5BFF",
opacity: 1,
keepShow: true, //是否即使 bar 不存在的情况下也保持显示
},
},
};
},
components: {
vuescroll,
},
methods: {
handleScroll (vertical, horizontal, nativeEvent) {
// vertical垂直方向滚动参数 horizontal 水平方向滚动参数
let width1 = this.$refs.scroll1[0].offsetWidth;
let w = horizontal.scrollLeft;
this.currentPage = Math.round(w / width1) + 1
},
handleCurrentChange (val) {
document.querySelector("#scroll" + val).scrollIntoView({ behavior: "smooth", block: "nearest", inline: "start" });
},
},
};
</script>
<style>
::-webkit-scrollbar {
width: 6px;
height: 0px;
}
::-webkit-scrollbar-thumb {
border-radius: 3px;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 1px rgba(0, 0, 0, 0);
border-radius: 3px;
background: #f0f2f5;
}
.box {
display: flex;
flex-direction: column;
align-items: center;
}
.out {
width: 320px;
border: 1px solid red;
/* overflow-x: hidden !important; */
position: relative;
}
.out::after {
content: '';
display: block;
position: absolute;
top: 0;
right: 0;
width: 10%;
height: 100%;
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
backdrop-filter: blur(0.5px);
/* 设置模糊度 */
}
/* 样式 */
.wrapper {
display: flex;
}
.content {
width: 284px;
height: 500px;
background-color: #ccc;
margin-right: 20px;
/* 排列时留出空隙 */
}
.content:last-child {
margin-right: 0;
}
</style>