vue 스크롤 로 딩 표 구현

실현 효과

코드 클 라 우 드 주소
스크롤 로드 지식 비축
ant-design-vue 에서 list 스크롤 로 딩 의 방향 을 참고 하여 vue-infinite-scroll 에 vue-virtual-scroller 를 솔 루 션 으로 사용 합 니 다.
모듈 패키지
전체 시스템 에서 사용 하 는 프레임 워 크 는 ant-dsign-vue 이기 때문에 구성 요소 가 포 장 된 변수 이름 스타일 은 가능 한 한 a-table 과 일치 합 니 다.
1.구성 요소 이름
XScrollTable.vue
2.props 제공
필수 필드:
dataSource--데이터 원본
columns-표 에 표 시 된 열 정보,슬롯 사용법 은 a-table 과 완전히 같 지 않 습 니 다.다음 에 언급 하 겠 습 니 다.
itemSize--줄 당 데이터 높이
필드 선택:
rowKey-데이터 메 인 키 표지,기본 값 은'key'입 니 다.
height--표 전시 영역의 높이,기본 값 500
pageSize--표 스크롤 이 스크롤 할 때마다 불 러 오 는 데 이 터 량,기본 값 은 30 입 니 다.
infinite ScrollDistance-표 가 불 러 오 는 거리 조건 을 촉발 합 니 다.기본 값 은 10 입 니 다.
rowSelection-표 다 중 선택 설정,처 리 된 속성 은 selected RowKeys,onChange,width 입 니 다.기본 값 은 null 입 니 다.다 중 선택 을 보 여주 지 않 습 니 다.
3.예시 사용
우선 10000 개의 데 이 터 를 초기 화하 여 표 에 표시 합 니 다.

let data = new Array(10000).fill(1);

data = data.map((item1, index) => {
    let item = {};
    item.id = index;
    item.age = "  ";
    item.address = "  ";
    return item;
});
export default data;
메모:여기에 fill(1)을 추가 한 이 유 는 Array 구조 함 수 를 통 해 발생 하 는 데 이 터 는 모두 empty 이 고 배열 색인 이 없어 map 순환 을 할 수 없 기 때 문 입 니 다.
표 불 러 오기

<x-scroll-table
                style="margin-top: 10px"
                row-key="id"
                :itemSize="22"
                :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,width:50}"
                :columns="columns"
                :dataSource="data">
            <template slot="action" slot-scope="{record,text}">
                <a @click="handleDetail(record)">  </a>
            </template>
        </x-scroll-table>
구성 요소 패키지 요약
1.가능 한 한 computed 를 사용 하여 속성 을 계산 합 니 다.
표 만 간단하게 봉 인 했 지만 많은 속성 을 정의 해 야 합 니 다.data 에서 변 수 를 정의 하 는 대신 계산 속성 을 사용 하면 변수의 유지 작업량 을 줄 일 수 있 습 니 다.
전체 구성 요 소 는 하나의 page 변수 만 정의 하고 다른 것 은 속성 을 계산 하 는 방식 을 사용 합 니 다.

  data() {
    return {
      //       
      page: 1,
    };
  },
밤 을 들다
page 속성 을 통 해 현재 불 러 온 데이터 의 양 을 계산 속성 으로 정의 합 니 다.

 //          ,            ,  slice      
    lastIndex() {
      return this.pageSize * this.page;
    },
이 계산 속성 을 통 해 다른 계산 속성 을 동시에 파생 시 킵 니 다.

//                 
busy() {
      return this.lastIndex >= this.dataSource.length;
    },
 //        RecycleScroller       
    tableData() {
      return this.dataSource.slice(0, this.lastIndex);
    },
하나의 page 속성 을 통 해 일련의 계산 속성 을 파생 시 킵 니 다.저 는 page 속성 만 유지 하고 다른 것 은 모두 자동 으로 계산 합 니 다.
2.표 에 슬롯 제공
먼저 표 에 들 어 오 는 columns 인 자 를 통 해 렌 더 링 이 필요 한 열 을 계산 합 니 다.여기 서도 계산 속성 을 사용 합 니 다.

 //          , columnFieldKey    ,      
    columnMap() {
      return this.columns.reduce((returnValue, cur) => {
        returnValue[cur[columnFieldKey]] = cur;
        return returnValue;
      }, {});
    },
    //         --columnFieldKey
    columnKeys() {
      return this.columns
          .map(item => item[columnFieldKey]);
    },
template 에 옮 겨 다 니 기

<div v-for="(key) of columnKeys"
             class="ellipsis-cell"
             :key="key"
             :style="itemStyle(columnMap[key])"
        >
          <slot v-if="izSlotRender(columnMap[key])"
                :name="columnMap[key].scopedSlots.customRender"
                :record="row"
                :text="row[key]">
          </slot>
          <span v-else :title="row[key]">{{ renderItem(row, index, key) }}</span>
        </div>

  //         
    izSlotRender(item) {
      return item.scopedSlots && item.scopedSlots.customRender;
    },
columns 를 정의 할 때 scoped Slots 와 customeRender 가 들 어 오 면 슬롯 렌 더 링 을 사용 합 니 다.
하지만 여기 에는 ant-design-vue 의 표 슬롯 렌 더 링 과 다른 부분 이 있 습 니 다.
저 는 slot 태그 로 정 의 된 슬롯 을 통 해 부모 구성 요소 가 슬롯 인 자 를 가 져 올 때 slot-scope="{record,text}"대상 만 재 구성 할 수 있 습 니 다.한편,ant-design-vue 표 는 slot-scope="record,text"를 직접 사용 하여 인 자 를 얻 을 수 있 습 니 다.
다른 스크롤 로 딩 데이터 구현
table 데이터 가 많 을 때 페이지 를 열 면 잠시 불 러 와 서 데 이 터 를 표시 합 니 다.체험 이 좋 지 않 기 때문에 스크롤 로 딩 데 이 터 를 해 야 합 니 다.

<el-table :data="materielList" style="width: 100%" class="familyDataDetail" height="250">
                <el-table-column prop="eventId" label="  ID">
                    <template scope="scope">
                        <label>{{eventMap[scope.row.eventId] == null ? '--': eventMap[scope.row.eventId].sn}}</label>
                    </template>
                </el-table-column>
                <el-table-column prop="title" label="    ">
                    <template scope="scope">
                        <label>{{eventMap[scope.row.eventId] == null ? '--': eventMap[scope.row.eventId].title}}</label>
                    </template>
                </el-table-column>
                <el-table-column prop="age" label="   ">
                    <template scope="scope">
                        <label>{{eventMap == null || eventMap[scope.row.eventId] == null || eventMap[scope.row.eventId].personalInformation == null ? '--':
                            eventMap[scope.row.eventId].personalInformation.name}}</label>
                    </template>
                </el-table-column>
                <el-table-column prop="birthday" label="    ">
                    <template scope="scope">
                        <label>{{materirlName}}</label>
                    </template>
                </el-table-column>
                <el-table-column prop="idcardNo" label="  ">
                    <template scope="scope">
                        <label>{{formatType(scope.row.type)}}</label>
                    </template>
                </el-table-column>
                <el-table-column prop="relationship" label="  ">
                    <template scope="scope">
                        <label>{{formatUseNum(scope.row.useNum)}}</label>
                    </template>
                </el-table-column>
                <el-table-column prop="ethtic" label="    ">
                    <template scope="scope">
                        <label>{{changeTime(scope.row.createOn)}}</label>
                    </template>
                </el-table-column>
            </el-table>
다음은 js 부분.

methods: {
  init (param) {
  let id = param.param && param.param.id
  if(id){
      this.start = 0
          MaterialRecordService.query({param: {baseId: this.baseId, materialId: id},start: this.start,limit: 30}).then(rsp => {//      ,30 
            this.start += 30
            this.materielList = rsp.data
            MissionEventService.microList({ids: rsp.data.map(n => n.eventId)}).then(rsp3 => {
                this.eventMap = {}
                rsp3.data.forEach(n => (this.eventMap[n.id] = n))
                 
            })   
          })
  }
  },
  onScroll() {
      let inner = document.querySelector('.el-table__body-wrapper');
      if(inner.scrollHeight - inner.scrollTop <= inner.clientHeight){// true       ,      
        if(this.flag){//          ,( data     flag: true)   true
             this.flag = false             
             MaterialRecordService.query({param: {baseId: this.baseId, materialId: this.entity.id},start: this.start,limit:30}).then(rsp => {//    30 
              this.materielList = this.materielList.concat(rsp.data)
                  this.start += 30
                  this.flag = true
              MissionEventService.microList({ids: rsp.data.map(n => n.eventId)}).then(rsp3 => {
               rsp3.data.forEach(n => (this.eventMap[n.id] = n))
              })
             })            
        }
      }
   }
},
mounted () {
      this.init({...this.param})<br>    //    dom       
      document.querySelector('.el-table__body-wrapper').addEventListener('scroll', this.onScroll);
    }
여기 서 감청 하 는 dom 대상 이 누구 인지 설명해 야 겠 어 요.

scrollHeight,scrollTop,client Height 라 는 세 가지 속성 을 설명해 야 겠 어 요.

이것 은 내 가 캡 처 한 다른 사람의 그림 에 몇 획 을 더 한 것 이다.
scrollHeight:웹 페이지 본문 전체 텍스트 높이,
scrollTop:웹 페이지 스크롤 높이,
clientHeight:웹 페이지 시각 영역 높이
이상 은 vue 가 스크롤 로 딩 을 실현 하 는 표 의 상세 한 내용 입 니 다.vue 스크롤 로 딩 표 에 대한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기