Element-ui之ElScrollBar组件滚动条的使用方法


Posted in Javascript onSeptember 14, 2018

在使用vue + element-ui 搭建后台管理页面的时候,做了一个头部、侧栏、面包屑固定的布局,导航栏和主要内容区域当内容超出时自动滚动。

使用的原因:

原来是采用优化浏览器样式的方式,对滚动条进行样式调整。但这个方法并不兼容火狐浏览器,在火狐访问时依然是浏览器默认的滚动条样式。

.sidebar {
 position: fixed;
 border-right: 1px solid rgba(0,0,0,.07);
 overflow-y: auto;
 position: absolute;
 top: 0;
 bottom: 0;
 left: 0;
 transition: transform .25s ease-out;
 width: 300px;
 z-index: 3;
}
.sidebar::-webkit-scrollbar {
 width: 4px
}

.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,0%,53%,.1)
}

灵感来源

在翻看 element-ui官网的文档时,发现其左侧导航和右边的内容超出屏幕时,滚动条的样式比较小巧,通过浏览器审查工具查看,发现它是使用了el-scrollbar的样式,跟element-ui的组件样式命名一致。但文档中并没有关于这个 scrollbar组件的使用文档,搜索一番得知这是一个隐藏组件,官方在 github 的 issues 中表示不会写在文档中,需要用的自己看源码进行调用。

最终实现效果

Element-ui之ElScrollBar组件滚动条的使用方法

实现步骤

一、阅读源码

通过阅读源码,scrollbar组件暴露了 native, wrapStyle, wrapClass, viewClass, viewStyle, noresize, tag 这7个 props属性

props: {
 native: Boolean, // 是否使用本地,设为true则不会启用element-ui自定义的滚动条
 wrapStyle: {}, // 包裹层自定义样式
 wrapClass: {}, // 包裹层自定义样式类
 viewClass: {}, // 可滚动部分自定义样式类
 viewStyle: {}, // 可滚动部分自定义样式
 noresize: Boolean, // 如果 container 尺寸不会发生变化,最好设置它可以优化性能
 tag: { // 生成的标签类型,默认使用 `div`标签包裹
  type: String,
  default: 'div'
 }
}

二、在页面中使用 el-scrollbar组件

<template>
 <div>
  <el-scrollbar :native="false" wrapStyle="" wrapClass="" viewClass="" viewStyle="" noresize="false" tag="section">
   <div>
    <p v-for="(item, index) in 200" :key="index">{{index}} 这里是一些文本。</p>
   </div>
  <el-scrollbar>
 </div>
</template>

以上代码就是对 el-scrollbar 的使用了,属性不需要用的就不用写。

源码

源码在node_modules 目录下的 element-ui/packages/scrollbar

模块入口index.js,从main导入 scrollbar并提供一个安装方法注册成全局组件

import Scrollbar from './src/main';

/* istanbul ignore next */
Scrollbar.install = function(Vue) {
 Vue.component(Scrollbar.name, Scrollbar);
};

export default Scrollbar;

src/main.js 源码

// reference https://github.com/noeldelgado/gemini-scrollbar/blob/master/index.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-bottom: ${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-scrollbar__view', this.viewClass],
  style: this.viewStyle,
  ref: 'resize'
 }, this.$slots.default);
 const wrap = (
  <div
  ref="wrap"
  style={ style }
  onScroll={ this.handleScroll }
  class={ [this.wrapClass, 'el-scrollbar__wrap', gutter ? '' : 'el-scrollbar__wrap--hidden-default'] }>
  { [view] }
  </div>
 );
 let nodes;

 if (!this.native) {
  nodes = ([
  wrap,
  <Bar
   move={ this.moveX }
   size={ this.sizeWidth }></Bar>,
  <Bar
   vertical
   move={ this.moveY }
   size={ this.sizeHeight }></Bar>
  ]);
 } else {
  nodes = ([
  <div
   ref="wrap"
   class={ [this.wrapClass, 'el-scrollbar__wrap'] }
   style={ style }>
   { [view] }
  </div>
  ]);
 }
 return h('div', { class: 'el-scrollbar' }, nodes);
 },

 methods: {
 handleScroll() {
  const wrap = this.wrap;

  this.moveY = ((wrap.scrollTop * 100) / wrap.clientHeight);
  this.moveX = ((wrap.scrollLeft * 100) / wrap.clientWidth);
 },

 update() {
  let heightPercentage, widthPercentage;
  const wrap = this.wrap;
  if (!wrap) return;

  heightPercentage = (wrap.clientHeight * 100 / wrap.scrollHeight);
  widthPercentage = (wrap.clientWidth * 100 / wrap.scrollWidth);

  this.sizeHeight = (heightPercentage < 100) ? (heightPercentage + '%') : '';
  this.sizeWidth = (widthPercentage < 100) ? (widthPercentage + '%') : '';
 }
 },

 mounted() {
 if (this.native) return;
 this.$nextTick(this.update);
 !this.noresize && addResizeListener(this.$refs.resize, this.update);
 },

 beforeDestroy() {
 if (this.native) return;
 !this.noresize && removeResizeListener(this.$refs.resize, this.update);
 }
};

示例

<div style="height: 100vh;">
 <!-- 注意需要给 el-scrollbar 设置高度,判断是否滚动是看它的height判断的 -->
 <el-scrollbar style="height: 100%;"> <!-- 滚动条 -->
  <div style="height: 500px;width: 100%;background: red;"></div>
  <div style="height: 500px;width: 100%;background: yellowgreen;"></div>
  <div style="height: 500px;width: 100%;background: blueviolet;"></div>
 </el-scrollbar><!-- /滚动条 -->
</div>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
Apr 12 Javascript
JS的反射问题
Apr 07 Javascript
被遗忘的javascript的slice() 方法
Apr 20 Javascript
关于JavaScript 原型链的一点个人理解
Jul 31 Javascript
BootStrap实现邮件列表的分页和模态框添加邮件的功能
Oct 13 Javascript
bootstrap table实现单击单元格可编辑功能
Mar 28 Javascript
Bootstrap Multiselect 常用组件实现代码
Jul 09 Javascript
Three.js中矩阵和向量的使用教程
Mar 19 Javascript
微信小程序 select 下拉框组件功能
Sep 09 Javascript
基于JavaScript获取base64图片大小
Oct 18 Javascript
JavaScript 装逼指南(js另类写法)
May 10 Javascript
React Native登录之指纹登录篇的示例代码
Nov 03 Javascript
node中的session的具体使用
Sep 14 #Javascript
vue3.0 CLI - 2.1 -  component 组件入门教程
Sep 14 #Javascript
vue3.0 CLI - 1 - npm 安装与初始化的入门教程
Sep 14 #Javascript
详解Vue CLI3配置解析之css.extract
Sep 14 #Javascript
vue-cli脚手架build目录下utils.js工具配置文件详解
Sep 14 #Javascript
vue3.0 CLI - 2.6 - 组件的复用入门教程
Sep 14 #Javascript
在vue项目中使用md5加密的方法
Sep 14 #Javascript
You might like
PHP利用COM对象访问SQLServer、Access
2006/10/09 PHP
php adodb连接mssql解决乱码问题
2009/06/12 PHP
php下通过curl抓取yahoo boss 搜索结果的实现代码
2011/06/10 PHP
用PHP实现的四则运算表达式计算实现代码
2011/08/02 PHP
CI框架源码解读之利用Hook.php文件完成功能扩展的方法
2016/05/18 PHP
php简单截取字符串代码示例
2016/10/19 PHP
php输出反斜杠的实例方法
2019/09/19 PHP
Laravel 验证码认证学习记录小结
2019/12/20 PHP
in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案
2011/07/26 Javascript
javascript表格的渲染组件
2015/07/03 Javascript
javaScript实现滚动新闻的方法
2015/07/30 Javascript
javascript html5 canvas实现可拖动省份的中国地图
2016/03/11 Javascript
辨析JavaScript中的Undefined类型与null类型
2016/05/26 Javascript
浅谈js中字符和数组一些基本算法题
2016/08/15 Javascript
jquery实现全选、不选、反选的两种方法
2016/09/06 Javascript
详解基于node的前端项目编译时内存溢出问题
2017/08/01 Javascript
vue-router重定向不刷新问题的解决
2018/06/25 Javascript
VUE 实现复制内容到剪贴板的两种方法
2019/04/24 Javascript
js实现简单商品筛选功能
2021/02/02 Javascript
[01:10]DOTA2次级职业联赛 - EP战队宣传片
2014/12/01 DOTA
python操作MySQL 模拟简单银行转账操作
2017/09/27 Python
Python Tkinter实现简易计算器功能
2018/01/30 Python
Python遍历某目录下的所有文件夹与文件路径
2018/03/15 Python
利用Pandas 创建空的DataFrame方法
2018/04/08 Python
Python实现爬虫抓取与读写、追加到excel文件操作示例
2018/06/27 Python
python 剪切移动文件的实现代码
2018/08/02 Python
详解Python计算机视觉 图像扭曲(仿射扭曲)
2019/03/27 Python
python机器人运动范围问题的解答
2019/04/29 Python
Django 权限认证(根据不同的用户,设置不同的显示和访问权限)
2019/07/24 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
2020/04/07 Python
Pytorch十九种损失函数的使用详解
2020/04/29 Python
HTML5通过调用canvas对象的getContext()方法来获取绘图环境
2014/06/23 HTML / CSS
美国购买舞会礼服网站:Couture Candy
2019/12/29 全球购物
《夹竹桃》教学反思
2016/02/23 职场文书
配置Kubernetes外网访问集群
2022/03/31 Servers
【DOTA2】高能暴走TK秀!PSG LGD vs ASTER - DPC 2022 WINTER TOUR CN
2022/04/02 DOTA