在使用vue + element-ui
搭建后台管理页面的时候,做了一个头部、侧栏、面包屑固定的布局,导航栏和主要内容区域当内容超出时自动滚动。
使用的原因:
原来是采用优化浏览器样式的方式,对滚动条进行样式调整。但这个方法并不兼容火狐浏览器,在火狐访问时依然是浏览器默认的滚动条样式。
.sidebar::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 4px
}
.sidebar:hover::-webkit-scrollbar-thumb {
background: hsla(0,0%,53%,.4)
}
.sidebar:hover::-webkit-scrollbar-track {
background: hsla(0,.1)
}
灵感来源
在翻看
element-ui
官网的文档时,发现其左侧导航和右边的内容超出屏幕时,滚动条的样式比较小巧,通过浏览器审查工具查看,发现它是使用了el-scrollbar的样式,跟element-ui的组件样式命名一致。但文档中并没有关于这个 scrollbar组件的使用文档,搜索一番得知这是一个隐藏组件,官方在 github 的 issues 中表示不会写在文档中,需要用的自己看源码进行调用。
最终实现效果
实现步骤
一、阅读源码
通过阅读源码,
scrollbar
组件暴露了native
,wrapStyle
,wrapClass
,viewClass
,viewStyle
,noresize
,tag
这7个 props属性
二、在页面中使用 el-scrollbar组件
以上代码就是对 el-scrollbar
的使用了,属性不需要用的就不用写。
源码
源码在node_modules
目录下的 element-ui/packages/scrollbar
模块入口index.js,从main导入 scrollbar并提供一个安装方法注册成全局组件
/ istanbul ignore next /
Scrollbar.install = function(Vue) {
Vue.component(Scrollbar.name,Scrollbar);
};
export default Scrollbar;
src/main.js 源码
import { addResizeListener,removeResizeListener } from 'element-ui/src/utils/resize-event';
import scrollbarWidth from 'element-ui/src/utils/scrollbar-width';
import { toObject } from 'element-ui/src/utils/util';
import Bar from './bar';
/ istanbul ignore next /
export default {
name: 'ElScrollbar',components: { Bar },props: {
native: Boolean,wrapStyle: {},wrapClass: {},viewClass: {},viewStyle: {},noresize: Boolean,// 如果 container 尺寸不会发生变化,最好设置它可以优化性能
tag: {
type: String,default: 'div'
}
},data() {
return {
sizeWidth: '0',sizeHeight: '0',moveX: 0,moveY: 0
};
},computed: {
wrap() {
return this.$refs.wrap;
}
},render(h) {
let gutter = scrollbarWidth();
let style = this.wrapStyle;
if (gutter) {
const gutterWith = -${gutter}px
;
const gutterStyle = margin-b<a href="https://www.jb51.cc/tag/ott/" target="_blank" class="keywords">ott</a>om: ${gutterWith}; margin-right: ${gutterWith};
;
if (Array.isArray(this.wrapStyle)) {
style = toObject(this.wrapStyle);
style.marginRight = style.marginBottom = gutterWith;
} else if (typeof this.wrapStyle === 'string') {
style += gutterStyle;
} else {
style = gutterStyle;
}
}
const view = h(this.tag,{
class: ['el-scrollbarview',this.viewClass],style: this.viewStyle,ref: 'resize'
},this.$slots.default);
const wrap = (
<div
ref="wrap"
style={ style }
onScroll={ this.handleScroll }
class={ [this.wrapClass,'el-scrollbarwrap',gutter ? '' : 'el-scrollbar__wrap--hidden-default'] }>
{ [view] }
if (!this.native) {
nodes = ([
wrap,<Bar
move={ this.moveX }
size={ this.sizeWidth }>,<Bar
vertical
move={ this.moveY }
size={ this.sizeHeight }>
]);
} else {
nodes = ([
<div
ref="wrap"
class={ [this.wrapClass,'el-scrollbar__wrap'] }
style={ style }>
{ [view] }