美文网首页
element UI scrollbar 源码学习和分析

element UI scrollbar 源码学习和分析

作者: 祁俊彩 | 来源:发表于2019-05-30 16:34 被阅读0次

scrollbar 源码解析的时候,我们不是为了弄懂它的每一行代码,但是我们必须学会它这种写scrollbar的思路,以及写法中充分利用vue的语法结构的学习。只有这样我们才能真正知道,写组件,尤其是写可以被广泛使用的公用组件的套路。ok,废话少说,开始进入枯燥的源码学习。请大家怀着一颗仁慈和包容的心态继续往下看,Come on,干起来!!!!

可以页面想象成一个长长的盒子,我们看到的是个视口。视口是不动的,盒子是移动的,当盒子向下滚动时,视口中所看到的盒子正在向下滚动。同样的,滚动块里面的滑块也往下移动同样比例的距离。

image image

文件夹结构

scrollbar组件在 package/scrollbar/index.js中注册,其中package/scrollbar/src 是代码的核心部分,入口文件是 main.js。

使用如下

image image

大家详细看一下注释,wrap是视口,view即内容可以滚动,horizontal 和 vertical是自定义滚动条。 下面开始撸代码,大家打起精神。走起!!!!!

main.js

main.js默认导出一个对象,接收一系列配置。


name: 'ElScrollbar',

components: { 
  //  滚动条组件,拥有水平与垂直两种形态
  Bar 
},

props: {
  native: Boolean,    //  是否使用原生滚动条,即不附加自定义滚动条
  wrapStyle: {},      //  wrap的内联样式
  wrapClass: {},      //  wrap的样式名
  viewClass: {},      //  view的样式名
  viewStyle: {},      //  view的内联样式
  noresize: Boolean,  //  当container尺寸发生变化时,自动更新滚动条组件的状态
  tag: {              //  组件最外层的标签属性,默认为 div
    type: String,
    default: 'div'
  }
},

data() {
  return {
    sizeWidth: '0',   //  水平滚动条的宽度
    sizeHeight: '0',  //  垂直滚动条的高度
    moveX: 0,         //  垂直滚动条的移动比例
    moveY: 0          //  水平滚动条的移动比例
  };
},

组件在render函数中生成结构。

tips: 如果在.vue文件中同时存在templete和 render 函数,组件实例会先取 template模板来渲染组件模板,而不是采用render函数

render函数一开始会通过scrollbarWidth 方法来计算当前浏览器的滚动条宽度

render(h) {
    //  获取浏览器的滚动条宽度
    let gutter = scrollbarWidth();
    //  wrap内联样式
    let style = this.wrapStyle;
    
    ...

scrollbarWidth 方法在scrollbar-width.js 中被默认导出

import Vue from 'vue';

//  闭包变量,用于记录滚动条宽度
let scrollBarWidth;

export default function() {
  //  如果在服务端运行,返回 0
  if (Vue.prototype.$isServer) return 0;
  //  如存在滚动条宽度,直接返回
  if (scrollBarWidth !== undefined) return scrollBarWidth;

  //  创建outer标签并隐藏
  const outer = document.createElement('div');
  outer.className = 'el-scrollbar__wrap';
  outer.style.visibility = 'hidden';
  outer.style.width = '100px';
  outer.style.position = 'absolute';
  outer.style.top = '-9999px';
  document.body.appendChild(outer);

  //  记录没有滚动内容的宽度
  const widthNoScroll = outer.offsetWidth;
  //  设置外层div滚动属性
  outer.style.overflow = 'scroll';
  //  创建inner标签,并追加到outer标签中
  const inner = document.createElement('div');
  inner.style.width = '100%';
  outer.appendChild(inner);
  //  此时outer已经可以滚动,记录下inner元素的宽度
  const widthWithScroll = inner.offsetWidth;
  //  销毁outer元素
  outer.parentNode.removeChild(outer);
  //  滚动条宽度 = 没有滚动条时的outer宽度 减去 有滚动条的outer中的inner宽度
  scrollBarWidth = widthNoScroll - widthWithScroll;
  //  返回滚动条宽度
  return scrollBarWidth;
};

得到滚动条方法会进行以下步骤
1、创建outer 容器,并记录outer容器offsetwidth
2、设置outer容器overflow:scroll,并新建inner容器,追加到outer容器下
3、此时outer容器会带着滚动条,记录inner容器的offsetwidth 宽度

相关文章

网友评论

      本文标题:element UI scrollbar 源码学习和分析

      本文链接:https://www.haomeiwen.com/subject/xomvtctx.html