(方法)基于 vue 自定义滚动条组件
vue中自定义滚动条,自定义宽度和颜色
·
个人项目地址: SubTopH前端开发个人站
(自己开发的前端功能和UI组件,一些有趣的小功能,感兴趣的伙伴可以访问,欢迎提出更好的想法,私信沟通,网站属于静态页面)
SubTopH前端开发个人站https://subtop.gitee.io/subtoph.github.io/#/home
以上 👆 是个人前端项目,欢迎提出您的建议😊
以下是正文内容...............
创建 vue 文件
- 创建组件文件 scrollContainer.vue
<template>
<div class="scrollbar-box" :style="{ height: height }">
<div class="scrollbar-y">
<div ref="scrollRef" class="scroll-wrap" @scroll="onMosewheel">
<slot></slot>
</div>
<div v-show="heightPre < 1" ref="barRef" class="scrollbar-track">
<div
:style="{
height: barHeight + 'px',
transform: 'translateY(' + translateY + 'px)',
}"
class="scrollbar-thumb"
@mousedown.stop.prevent="moveStart"
></div>
</div>
</div>
</div>
</template>
<script>
export default {
components: {},
props: {
height: {
type: String,
default: "100%",
},
},
data() {
return {
isMove: false,
trackHeight: 0, // 滚动条轨道高度
wrapHeight: 0, // 容器高度(可视高度)
wrapContentHeight: 0, // 内容高度(可滚动内容的高度)
translateY: 0,
moveClientY: 0,
scrollTop: 0,
};
},
computed: {
barHeight() {
return this.heightPre * this.trackHeight;
},
// 可视高度与内容高度的比例
heightPre() {
return this.wrapHeight / this.wrapContentHeight;
},
},
watch: {},
// 生命周期 - 创建完成(可以访问当前this实例)
created() {},
// 生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
this.initScrollListner();
},
activated() {},
methods: {
initScrollListner(e) {
const scroll = this.$refs.scrollRef;
const bar = this.$refs.barRef;
this.wrapContentHeight = scroll.scrollHeight;
this.wrapHeight = scroll.clientHeight;
this.trackHeight = bar.clientHeight;
},
updateScroll() {
this.initScrollListner();
},
onMosewheel(e) {
this.scrollY(e.target.scrollTop * this.heightPre);
},
scrollY(y) {
this.translateY = y;
},
// 鼠标开始移动
moveStart(e) {
this.isMove = true;
// 开始移动时鼠标距离thumb顶部的位置
this.moveClientY = e.clientY - this.translateY;
this.moveTo();
this.moveEnd();
},
// 鼠标移动,改变thumb的位置以及容器scrollTop的位置
moveTo() {
document.onmousemove = (e) => {
if (this.isMove) {
if (
e.clientY - this.moveClientY >
this.trackHeight - this.barHeight
) {
this.translateY = this.trackHeight - this.barHeight;
} else if (e.clientY - this.moveClientY < 0) {
this.translateY = 0;
} else {
this.translateY = e.clientY - this.moveClientY;
}
this.$refs.scrollRef.scrollTop = this.translateY / this.heightPre;
}
};
},
// 鼠标移动结束
moveEnd() {
document.onmouseup = (e) => {
if (this.isMove) {
this.isMove = false;
}
};
},
},
};
</script>
<style lang="less" scoped>
.scrollbar-box {
height: 600px;
overflow: hidden;
}
.scrollbar-y {
position: relative;
height: 100%;
margin-right: -17px;
.scroll-wrap {
height: 100%;
overflow-y: scroll;
}
.scrollbar-track {
position: absolute;
top: 0;
right: 17px;
bottom: 0;
width: 16px;
background-color: #000000; //背景
border-radius: 8px;
z-index: 20;
.scrollbar-thumb {
width: 12px;
margin: 0 auto;
height: 20%;
background-color: #eeeeee; //滑块
border-radius: 6px;
cursor: default;
// transition: all 0.01s;
}
}
}
</style>
- 组件内引入注册使用
<template>
<!-- 组件列表展示 -->
<div class="content">
<!-- 滚动条盒子 -->
<div id="scrollContainer" class="layout">
<p class="tit">自定义滚动条(scrollContainer)</p>
<div class="layout-box">
<scrollContainer
ref="scrollbarRef"
height="100%"
class="scroll-container"
>
<ul v-for="item in 17" :key="item">
<li>{{ item }} 信息列表</li>
</ul>
</scrollContainer>
</div>
</div>
</div>
</template>
<script>
//引入封装滚动条组件
import ScrollbarContainer from '@/components/scrollbar/index.vue'
export default {
components: {
//注册组件
ScrollbarContainer
},
mounted() {
// *注:demo更新需要更新容器
this.$nextTick(() => {
this.$refs.scrollbarRef.updateScroll()
})
}
}
</script>
<style lang="less" scoped>
.layout {
padding: 20px;
width: 90%;
margin: 0 auto;
margin-top: 30px;
box-sizing: border-box;
.tit {
margin: 10px 0;
box-sizing: border-box;
font-size: 20px;
font-weight: 700px;
}
}
// 滚动条盒子
.layout-box {
border: 1px solid #ddd;
margin: 0 auto;
height: 200px;
}
</style>
- 全局注册使用
// index.js引入注册组件
import ScrollbarContainer from "./scrollContainer.vue";
function plugins(Vue) {
Vue.component("ScrollbarContainer", ScrollbarContainer);
}
export default plugins;
// main.js全局引入组件,组件中直接标签使用即可
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// 引入组件
import plugins from './components/index'
// 注册组件
Vue.use(plugins);
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
更多推荐
已为社区贡献4条内容
所有评论(0)