ant desing vue table 신축 열 을 실현 하 는 전체 예

ant-design-vue table 신축 열 문 제 를 완벽 하 게 해결 하여 고정 열,다단 계 표 두 상황 에서 의 신축 열 을 실현 합 니 다.
이 물건 은 원래 손 쉽게 잡 을 수 있다 고 생각 했 는데 홈 페이지 에서 이미 예 를 들 었 기 때문이다.그러나 역시 공식 을 너무 믿 지 못 한다.정부 에서 준 것 은 가장 기본 적 인 것 일 뿐이다.그리고 우리 가 정상적으로 사용 하 는 장면 은 매우 복잡 하 다.예 를 들 어 고정 열,예 를 들 어 고정 표,예 를 들 어 자체 checkbox 열,예 를 들 어 다단 계 표 의 상황 등 이다.이런 상황 을 만족 시 키 려 면 종종 자체 개발 이 필요 하 다.
1.우선 장 씨 의 공식 적 인 예 를 들 어 copy 를 내 려 놓 고 미 루 지 못 한다.
공식 을 대조 해 보 니 css 가 다 르 기 때문에 첫 번 째 변경 사항 이 추가 되 었 다.
style 내 연 스타일 은 translate 속성 을 가지 고 있 기 때문에 right:0 을 직접 제거 합 니 다.left-5.height 만 100%설정 하면 됩 니 다.

.resize-table-th {
    position: relative;
    .table-draggable-handle {
      height: 100% !important;
      bottom: 0;
      left: -5px !important;
      cursor: col-resize;
      touch-action: none;
      position: absolute;
    }
  }
2.드래그 할 때마다 translate 속성 이 실시 간 으로 변 하 는 것 을 볼 수 있 지만 셀 은 넓 어 지지 않 고 이동 합 니 다.
그래서 요 소 를 검 사 했 는데 th 의 width 가 변화 하고 있 음 을 발 견 했 지만 colGroup 의 width 속성 은 변 하지 않 았 습 니 다.그래서 해당 하 는 colGroup 의 하위 요소 인 col 을 찾 는 여행 을 시 작 했 습 니 다.마지막 으로 찾 았 습 니 다.그 다음 에 draging 을 할 때 colGroup 의 col width 속성 을 동시에 수정 하 였 습 니 다.이렇게 하면 따라서 변화 할 수 있다.
3.그 다음 에 나 는 고정 열 과 고정 표 두 의 상황 에서 늘 어 나 면 bug 가 나타 나 는 것 을 발견 했다.
코드 를 보면 고정된 열 이나 고정된 헤더 인 경우 실제 thead 와 tbody 는 다른 table 에 있 습 니 다.이 럴 때 모든 colGroup 테스트 col 을 찾 아 width 를 바 꿔 야 합 니 다.이렇게 해서 고정 헤드 의 스 트 레 칭 을 처리 하 였 습 니 다.그러나 고정 열의 경우 css 를 따로 설정 하고 table-fixed-left 를 찾 아 폭 을 다시 설정 해 야 합 니 다.
다음은 코드 들 입 니 다.
현재 의 th 에 따라 th 는 부모 요소 의 몇 번 째 아이 노드 로 colGroup 의 몇 번 째 col 노드 에 대응 합 니 다.

const loopDom = ss => {
  if (ss.previousSibling !== null) {
    thDomIndex++;
    loopDom(ss.previousSibling);
  }
};
고정 열의 폭 을 다시 설정 합 니 다.(왼쪽 유동 만 처 리 했 습 니 다)

function resetFixedColumns(width) {
  const fixedHead = document.querySelector(".ant-table-fixed-left .ant-table-header");
  const fixedBody = document.querySelector(".ant-table-fixed-left .ant-table-body-outer .ant-table-fixed");
  if (fixedHead) {
    fixedHead.style.width = width + "px";
    fixedBody.style.width = width + "px";
  }
}
다단 계 헤드 신축 열 문 제 를 해결 하 다.
배열 을 재 귀적 으로 옮 겨 다 니 며 폭 가 져 오기

getDraggingMap(tbCols, draggingMap) {
      tbCols.forEach(col => {
        if (col.children) {
          this.getDraggingMap(col.children, draggingMap);
        } else {
          const key = col.dataIndex || col.key; //                
          draggingMap[key] = col.width || 0;
        }
      });
    },
배열 을 옮 겨 다 니 며 현재 열 을 가 져 옵 니 다.(이 재 귀 는 정말 귀 찮 습 니 다.재 귀 를 쓰 는 것 이 어떤 느낌 인지 모 르 겠 습 니 다)

//       
    getRenderCoL(key, tbCols) {
      let result = "";
      this._.forEach(tbCols, item => {
        if (item.children) {
          result = this.getRenderCoL(key, item.children);
          return !result;
        } else {
          const k = item.dataIndex || item.key;
          if (k === key) {
            result = item;
            return false;
          }
        }
      });
      return result;
    }
배열 을 재 귀적 으로 옮 겨 다 니 며 다단 계 헤더 작업 열 색인 을 가 져 옵 니 다.

 const loopDom = (cols, col) => {
          let tag = true;
          this._.forEach(cols, co => {
            if (co.dataIndex == col.dataIndex) {
              thDomIndex++;
              tag = false;
              return tag;
            }
            if (co.children) {
              tag = loopDom(co.children, col);
              return tag;
            } else {
              thDomIndex++;
            }
          });
          return tag;
        };
다음은 전체 코드 입 니 다.
이것 은 js 파일 입 니 다.mixin 방식 으로 table 메 인 파일,table 추가

:components="drag(columnKeys)"

//mixins/tableDragResize.js
import Vue from "vue";
import VueDraggableResizable from "vue-draggable-resizable";
Vue.component("vue-draggable-resizable", VueDraggableResizable);

export default {
  data() {
    return {
      maxLevel: 1
    };
  },
  methods: {
    drag(columns) {
      return {
        header: {
          cell: this.initDrag(columns)
        }
      };
    },
    /**
     * @param {   columns } tbCols
     */
    initDrag(tbCols) {
      let draggingMap = {};
      this.getDraggingMap(tbCols, draggingMap, 1);
      let draggingState = Vue.observable(draggingMap);
      return (h, props, children) => {
        let thDomIndex = 0;
        const { key, ...restProps } = props;
        let col = {};
        //       
        col = this.getRenderCoL(key, tbCols);
        if (!col || !col.width) {
          //            width  ,               
          return <th {...restProps}>{children}</th>;
        }
        const onDrag = x => {
          col.width = Math.max(x, 1);
          draggingState[key] = col.width;
          thDomIndex = 0;
          loopDom(tbCols, col);
          if (!this.attrBute.isCheck) {
            thDomIndex--;
          }
          let colgroup = document.querySelectorAll("colgroup");
          colgroup.forEach(Element => {
            let childCol = Element.children;
            if (childCol[thDomIndex]) childCol[thDomIndex].style.width = col.width + "px";
          });
          this.resetFixedColumns(col.width);
        };
        const loopDom = (cols, col) => {
          let tag = true;
          this._.forEach(cols, co => {
            if (co.dataIndex == col.dataIndex) {
              thDomIndex++;
              tag = false;
              return tag;
            }
            if (co.children) {
              tag = loopDom(co.children, col);
              return tag;
            } else {
              thDomIndex++;
            }
          });
          return tag;
        };
        const onDragstop = () => {};

        return (
          <th {...restProps} width={draggingState[key]} class="resize-table-th" dataIndex={col.key}>
            {children}
            <vue-draggable-resizable
              key={col.dataIndex || col.key}
              class="table-draggable-handle"
              w={20}
              h={this.getResizableHandler(col)}
              x={draggingState[key]}
              z={100}
              axis="x"
              draggable={true}
              resizable={false}
              onDragging={onDrag}
              onDragstop={onDragstop}
            ></vue-draggable-resizable>
          </th>
        );
      };
    },
    getResizableHandler(col) {
      // let baseH = thDom.getBoundingClientRect().height;
      let size = this.cellsize ? this.cellsize : this.attrBute.cellsize;
      let baseH = size == "middle" ? 47 : size == "small" ? 39 : 55;
      if (col.isEndNode) return baseH * col.nodeLevel;
      else if (col.leafNode && col.nodeLevel < this.maxLevel) {
        return baseH * this.maxLevel;
      } else return baseH;
    },
    resetFixedColumns(width) {
      const fixedHead = document.querySelector(".ant-table-fixed-left .ant-table-header");
      const fixedBody = document.querySelector(".ant-table-fixed-left .ant-table-body-outer .ant-table-fixed");
      if (fixedHead) {
        fixedHead.style.width = width + "px";
        fixedBody.style.width = width + "px";
      }
    },
    getDraggingMap(tbCols, draggingMap, nodeLevel) {
      tbCols.forEach((col, index) => {
        col.nodeLevel = nodeLevel;
        col.isEndNode = index == tbCols.length - 1;
        this.maxLevel = Math.max(this.maxLevel, nodeLevel);
        if (col.children) {
          col.leafNode = false;
          this.getDraggingMap(col.children, draggingMap, nodeLevel + 1);
        } else {
          col.leafNode = true;
          const key = col.dataIndex || col.key; //                
          draggingMap[key] = col.width || 0;
        }
      });
    },
    getRenderCoL(key, tbCols) {
      let result = "";
      this._.forEach(tbCols, item => {
        if (item.children) {
          result = this.getRenderCoL(key, item.children);
          return !result;
        } else {
          const k = item.dataIndex || item.key;
          if (k === key) {
            result = item;
            return false;
          }
        }
      });
      return result;
    }
  }
};
후 기 는 다단 계 헤더 의 신축 열 을 완벽 하 게 해결 하고 원래 getDraggingMap 방법 을 수정 하 며 node Level 등급 을 증가 합 니 다.isEndNode 는 뚜껑 등급 의 마지막 노드 인지,그리고 this.max Level 기록 의 최대 등급 입 니 다.

getDraggingMap(tbCols, draggingMap, nodeLevel) {
tbCols.forEach((col, index) => {
col.nodeLevel = nodeLevel;
col.isEndNode = index == tbCols.length - 1;
this.maxLevel = Math.max(this.maxLevel, nodeLevel);
if (col.children) {
col.leafNode = false;
this.getDraggingMap(col.children, draggingMap, nodeLevel + 1);
} else {
col.leafNode = true;
const key = col.dataIndex || col.key; //                
draggingMap[key] = col.width || 0;
}
});
},
table-draggable-handle 을 처리 하 는 높이 를 늘 리 는 방법
그림 을 보다
在这里插入图片描述
드래그 가능 구역 은 빨간색 구역 입 니 다.이 효 과 를 얻 기 위해 서 는 다음 과 같은 처리 가 필요 합 니 다.
먼저 css 의 height:100%제거 하기;
그리고 render 에서 구성 요소 높이 를 다음 과 같이 설정 합 니 다.

h={this.getResizableHandler(col)}
사이즈

getResizableHandler(col) {
      // let baseH = thDom.getBoundingClientRect().height;
      let size = this.cellsize ? this.cellsize : this.attrBute.cellsize;
      let baseH = size == "middle" ? 47 : size == "small" ? 39 : 55;
      if (col.isEndNode) return baseH * col.nodeLevel;
      else if (col.leafNode && col.nodeLevel < this.maxLevel) {
        return baseH * this.maxLevel;
      } else return baseH;
    },
완결
이상 은 ant desing vue table 이 신축 가능 열 을 실현 하 는 상세 한 내용 입 니 다.ant desing vue table 의 신축 가능 열 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기