固定列和表格头的表格实现

前言

脱离element-ui又借鉴element-ui,实现类似el-table的固定列和表头的效果

  • 1-1固定,1-2只支持上下滑动,2-1只支持左右滑动,2-2上下、左右均可滑动
  • 其中下图中1-2和2-1两part的滑动事件应用了el-table的mousewheel
效果
scroll效果
布局分割
实现

布局

<div class="tree_table" v-on="handleBodyScroll, resize: handleBodyScroll }">
   <!-- 右侧活动区(2-1、2-2) -->
    <div class="scroll_table" ref="tableScroll">
      <!-- 2-1 -->
        <div class="header" ref="scrollHead" v-mousewheel="handleHeaderMousewheel">
            <ul class="header_row row" :style="{ 'width': ulBoxWidth }">
               <li v-for="(date, index) in dateTitList" :key="'head' + index">
                    {{ date.dateText }}
               </li>  
            </ul>
        </div>
        <!-- 2-2 -->
        <div class="body" ref="tableContent">
            <ul v-for="(item, index) in list" :key="index" class="row" :style="{ 'width': ulBoxWidth }" @mouseenter="handleMouseEnter(index)" @mouseleave="handleMouseLeave(index)">
               <li v-for="(date, index) in dateTitList" :key="'body' + index" class="border-dash">
                   <span>1</span>
               </li>
            </ul>
        </div>
    </div>
    <!-- 左侧固定区(1-1、1-2) -->
    <div class="fixed_table" :class="{'table-fixed-left-scroll': hasLeft}">
        <!-- 1-1 -->
        <div class="fixed_header">  
             <ul class="header_row row">
                  <li>项目</li>
             </ul>
        </div>
      <!-- 1-2 -->
        <div class="fixed_cont" ref="fixedBody" v-mousewheel="handleFixedMousewheel">
            <ul v-for="(item, index) in list" :key="'fixed_item' + index" class="row" @mouseenter="handleMouseEnter(index)" @mouseleave="handleMouseLeave(index)">
                <li class="border-dash">{{ item.title }}</li>
            </ul>
        </div>
    </div>
</div>

主要方法

// 滚动右侧body区触发
handleBodyScroll(event) {
  this.scrollValue = this.bodyWrapper.scrollLeft
  this.hasLeft = this.scrollValue > 0
  this.$refs.fixedBody.scrollTop = this.bodyWrapper.scrollTop
  this.$refs.scrollHead.scrollLeft = this.scrollValue
},
// 滚动左侧固定列触发
handleFixedMousewheel(event, data) {
  const bodyWrapper = this.bodyWrapper
  if (Math.abs(data.spinY) > 0) {
    const currentScrollTop = this.bodyWrapper.scrollTop
    if (data.pixelY < 0 && currentScrollTop !== 0) {
      event.preventDefault()
    }
    if (data.pixelY > 0 && bodyWrapper.scrollHeight - bodyWrapper.clientHeight > currentScrollTop) {
      event.preventDefault()
    }
    bodyWrapper.scrollTop += Math.ceil(data.pixelY / 5)
  } else {
    bodyWrapper.scrollLeft += Math.ceil(data.pixelX / 5)
  }
},
// 滚动头部日期组触发
handleHeaderMousewheel(event, data) {
  const { pixelX, pixelY } = data;
  if (Math.abs(pixelX) >= Math.abs(pixelY)) {
    event.preventDefault();
    this.bodyWrapper.scrollLeft += data.pixelX / 5;
  }
}

element-ui的mousewheel

import normalizeWheel from 'normalize-wheel'

const isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;

const mousewheel = function(element, callback) {
  if (element && element.addEventListener) {
    element.addEventListener(isFirefox ? 'DOMMouseScroll' : 'mousewheel', function(event) {
      const normalized = normalizeWheel(event);
      callback && callback.apply(this, [event, normalized]);
    });
  }
};

export default {
  bind(el, binding) {
    mousewheel(el, binding.value);
  }
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。