Element UI
中内置的滚动条插件el-scrollbar
,但没有公示在文档中,这里基于它封装一个组件,提供回到顶部、滚动放向、最大高度功能。完整代码在最后。
基础结构
接收height
属性,可以动态设置高度,默认是100%
<template>
<el-scrollbar
:class="['scroll-bar']"
ref="scroll"
:style="style">
<slot />
el-scrollbar>
template>
<script>
export default {
props: {
height: {
type: String,
default () {
return '100%'
}
}
},
data () {
return {
}
},
computed: {
style () {
return {
height: this.height
}
}
},
methods: {
}
}
script>
<style lang="scss">
.scroll-bar {
.el-scrollbar__wrap {
overflow-x: hidden; // 去除横向滚动条
}
}
style>
<style lang="scss" scoped>
style>
引入页面即可使用,注意百分比需要父级有高度,这种常用组件可以全局注册,使用更加便捷。
<template>
<div style="width: 400px; height: 400px; margin: 0 auto;">
<scroll-bar>
<ul>
<li
v-for="item in 100"
:key="item">{{ item }}li>
ul>
scroll-bar>
div>
template>
<script>
import ScrollBar from '@/components/ScrollBar'
export default {
components: {
ScrollBar
}
}
script>
回到顶部
接收toTop
属性,需要显示回到顶部按钮设置,默认是false
<template>
<el-scrollbar
:class="['scroll-bar']"
ref="scroll"
:style="style">
<slot />
<div
v-show="showToTop"
class="to-top"
:style="[
{'background-color': toTopTheme.bgc},
{'color': toTopTheme.color},
{'right': toTopPos.right},
{'bottom': toTopPos.bottom}
]"
@click="handleToTop">
<i class="el-icon-top">i>
div>
el-scrollbar>
template>
<script>
export default {
props: {
height: {
type: String,
default () {
return '100%'
}
},
toTop: {
type: Boolean,
default () {
return false
}
},
toTopTheme: {
type: Object,
default () {
return {
bgc: '',
color: ''
}
}
},
toTopPos: {
type: Object,
default () {
return {
right: '',
bottom: ''
}
}
}
},
data () {
return {
showToTop: false
}
},
computed: {
style () {
return {
height: this.height
}
}
},
mounted () {
this.toTop && this.$refs.scroll.wrap.addEventListener('scroll', this.scrollFunc)
},
methods: {
scrollFunc (e) {
const scrollTop = e.target.scrollTop
if (scrollTop > 80) {
this.showToTop = true
} else {
this.showToTop = false
}
},
handleToTop () {
// el-scrollbar滚动层为wrap
this.$refs.scroll.wrap.scrollTo({
top: 0,
behavior: 'smooth'
})
}
}
}
script>
<style lang="scss">
.scroll-bar {
.el-scrollbar__wrap {
overflow-x: hidden; // 去除横向滚动条
}
}
style>
<style lang="scss" scoped>
.to-top {
width: 32px;
height: 32px;
border-radius: 8px;
text-align: center;
line-height: 35px;
position: absolute;
bottom: 40px;
right: 20px;
background-color: #3756d4;
color: #fff;
font-size: 20px;
transition: all .4s;
.el-icon-top {
transition: all .4s;
}
&:hover {
cursor: pointer;
opacity: .88;
}
&.active {
.el-icon-top {
transform: translateY(-6px);
}
}
}
style>
- {{ item }}
横向滚动
接收direction
属性,控制滚动方向,默认为y
,这里主要通过改变样式实现。
<template>
<el-scrollbar
:class="['scroll-bar', {'direction-x': direction === 'x'}]"
ref="scroll"
:style="style">
<slot />
<div
v-show="showToTop"
class="to-top"
:style="[
{'background-color': toTopTheme.bgc},
{'color': toTopTheme.color},
{'right': toTopPos.right},
{'bottom': toTopPos.bottom}
]"
@click="handleToTop">
<i class="el-icon-top">i>
div>
el-scrollbar>
template>
<script>
export default {
props: {
height: {
type: String,
default () {
return '100%'
}
},
toTop: {
type: Boolean,
default () {
return false
}
},
toTopTheme: {
type: Object,
default () {
return {
bgc: '',
color: ''
}
}
},
toTopPos: {
type: Object,
default () {
return {
right: '',
bottom: ''
}
}
},
direction: {
type: String,
default () {
return 'y'
}
}
},
data () {
return {
showToTop: false
}
},
computed: {
style () {
return {
height: this.height
}
}
},
mounted () {
this.toTop && this.$refs.scroll.wrap.addEventListener('scroll', this.scrollFunc)
},
methods: {
scrollFunc (e) {
const scrollTop = e.target.scrollTop
if (scrollTop > 80) {
this.showToTop = true
} else {
this.showToTop = false
}
},
handleToTop () {
// el-scrollbar滚动层为wrap
this.$refs.scroll.wrap.scrollTo({
top: 0,
behavior: 'smooth'
})
}
}
}
script>
<style lang="scss">
.scroll-bar {
&.direction-x {
.el-scrollbar__wrap{
overflow-x: auto !important;
height: calc(100% + 20px);
.el-scrollbar__view{
height: 100%;
}
}
}
.el-scrollbar__wrap {
overflow-x: hidden;
}
}
style>
<style lang="scss" scoped>
.to-top {
width: 32px;
height: 32px;
border-radius: 8px;
text-align: center;
line-height: 35px;
position: absolute;
bottom: 40px;
right: 20px;
background-color: #3756d4;
color: #fff;
font-size: 20px;
transition: all .4s;
.el-icon-top {
transition: all .4s;
}
&:hover {
cursor: pointer;
opacity: .88;
}
&.active {
.el-icon-top {
transform: translateY(-6px);
}
}
}
style>
<template>
<div style="width: 400px; height: 400px; margin: 0 auto;">
<scroll-bar direction="x">
<ul>
<li
v-for="item in 100"
:key="item">{{ item }}li>
ul>
scroll-bar>
div>
template>
<script>
import ScrollBar from '@/components/ScrollBar'
export default {
components: {
ScrollBar
},
data () {
return {
}
},
methods: {
}
}
script>
<style lang="scss" scoped>
ul {
display: flex;
flex-wrap: nowrap;
li {
width: 100px;
}
}
style>
最大高度(完整代码)
接收maxHeight
属性,动态内容不设置固定高度时使用,通过给容器el-scrollbar__wrap
设置最大高度实现。
<template>
<el-scrollbar
:class="['scroll-bar', {'direction-x': direction === 'x'}, {'max-height': maxHeight}]"
ref="scroll"
:style="style">
<slot />
<div
v-show="showToTop"
class="to-top"
:style="[
{'background-color': toTopTheme.bgc},
{'color': toTopTheme.color},
{'right': toTopPos.right},
{'bottom': toTopPos.bottom}
]"
@click="handleToTop">
<i class="el-icon-top">i>
div>
el-scrollbar>
template>
<script>
export default {
props: {
height: {
type: String,
default () {
return '100%'
}
},
maxHeight: {
type: String
},
toTop: {
type: Boolean,
default () {
return false
}
},
toTopTheme: {
type: Object,
default () {
return {
bgc: '',
color: ''
}
}
},
toTopPos: {
type: Object,
default () {
return {
right: '',
bottom: ''
}
}
},
direction: {
type: String,
default () {
return 'y'
}
}
},
data () {
return {
showToTop: false
}
},
computed: {
style () {
return {
height: this.height,
'--maxHeight': this.maxHeight || ''
}
}
},
mounted () {
this.toTop && this.$refs.scroll.wrap.addEventListener('scroll', this.scrollFunc)
},
methods: {
scrollFunc (e) {
const scrollTop = e.target.scrollTop
if (scrollTop > 80) {
this.showToTop = true
} else {
this.showToTop = false
}
},
handleToTop () {
// el-scrollbar滚动层为wrap
this.$refs.scroll.wrap.scrollTo({
top: 0,
behavior: 'smooth'
})
}
}
}
script>
<style lang="scss">
.scroll-bar {
&.direction-x {
.el-scrollbar__wrap{
overflow-x: auto !important;
height: calc(100% + 20px);
.el-scrollbar__view{
height: 100%;
}
}
}
&.max-height {
.el-scrollbar__wrap {
max-height: var(--maxHeight);
overflow-x: hidden;
}
}
.el-scrollbar__wrap {
overflow-x: hidden;
}
}
style>
<style lang="scss" scoped>
.to-top {
width: 32px;
height: 32px;
border-radius: 8px;
text-align: center;
line-height: 35px;
position: absolute;
bottom: 40px;
right: 20px;
background-color: #3756d4;
color: #fff;
font-size: 20px;
transition: all .4s;
.el-icon-top {
transition: all .4s;
}
&:hover {
cursor: pointer;
opacity: .88;
}
&.active {
.el-icon-top {
transform: translateY(-6px);
}
}
}
style>
<template>
<div style="width: 400px; margin: 0 auto;">
<scroll-bar maxHeight="200px">
<ul>
<li
v-for="item in 100"
:key="item">{{ item }}li>
ul>
scroll-bar>
div>
template>
<script>
import ScrollBar from '@/components/ScrollBar'
export default {
components: {
ScrollBar
},
data () {
return {
}
},
methods: {
}
}
script>