| | |
| | | <app-header title="交通统计报表审核系统 - 数据查看"></app-header> |
| | | <el-container> |
| | | <el-aside width="200px"> |
| | | <el-menu router default-active="/data"> |
| | | <el-menu ref="sideMenu" router :default-active="$route.path" @select="onMenuSelect"> |
| | | <el-menu-item index="/dashboard">工作台</el-menu-item> |
| | | <el-menu-item index="/import">数据导入</el-menu-item> |
| | | <el-menu-item index="/data">数据查看</el-menu-item> |
| | |
| | | <div style="color:#909399;font-size:12px;margin-bottom:6px"> |
| | | 共 {{ total }} 条记录,当前第 {{ page }} 页 |
| | | </div> |
| | | <div class="table-area" ref="tableArea"> |
| | | <el-table :data="records" border v-loading="loading" size="small" style="width:100%" height="100%"> |
| | | <el-table-column v-for="c in columns" :key="c.prop" :prop="c.prop" :label="c.label" :min-width="c.width" show-overflow-tooltip> |
| | | <template slot-scope="scope"> |
| | | <span>{{ formatCell(scope.row[c.prop]) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div class="table-wrap" ref="tableWrap"> |
| | | <div class="table-area"> |
| | | <el-table :data="records" border v-loading="loading" size="small" style="width:100%" height="100%"> |
| | | <el-table-column v-for="c in columns" :key="c.prop" :prop="c.prop" :label="c.label" :min-width="c.width" show-overflow-tooltip> |
| | | <template slot-scope="scope"> |
| | | <span>{{ formatCell(scope.row[c.prop]) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <el-pagination style="margin-top:15px;text-align:right" |
| | | background layout="total, prev, pager, next, sizes" |
| | | :total="total" :current-page.sync="page" :page-size.sync="size" |
| | | :page-sizes="[20, 50, 100]" @current-change="loadData" @size-change="loadData"> |
| | | </el-pagination> |
| | | </div> |
| | | <el-pagination style="margin-top:15px;text-align:right" |
| | | background layout="total, prev, pager, next, sizes" |
| | | :total="total" :current-page.sync="page" :page-size.sync="size" |
| | | :page-sizes="[20, 50, 100]" @current-change="loadData" @size-change="loadData"> |
| | | </el-pagination> |
| | | </el-main> |
| | | </el-container> |
| | | </el-container> |
| | |
| | | total: 0, |
| | | records: [], |
| | | columns: [], |
| | | loading: false |
| | | loading: false, |
| | | loadingMore: false |
| | | } |
| | | }, |
| | | methods: { |
| | | loadData() { |
| | | this.loading = true |
| | | this.loadingMore = false |
| | | api.get('/data/list', { |
| | | params: { |
| | | type: this.type, |
| | |
| | | this.$message.error('数据查询失败') |
| | | }).finally(() => { |
| | | this.loading = false |
| | | this.$nextTick(() => this.attachBodyScroll()) |
| | | }) |
| | | }, |
| | | // el-table 固定高度后,真正的竖向滚动容器是内部的 body-wrapper(页面本身不滚动) |
| | | attachBodyScroll() { |
| | | const wrap = this.$refs.tableWrap |
| | | if (!wrap) return |
| | | const bw = wrap.querySelector('.el-table__body-wrapper') |
| | | if (bw && bw._vwScrollHandler !== this.onScroll) { |
| | | if (bw._vwScrollHandler) bw.removeEventListener('scroll', bw._vwScrollHandler) |
| | | bw.addEventListener('scroll', this.onScroll, { passive: true }) |
| | | bw._vwScrollHandler = this.onScroll |
| | | } |
| | | }, |
| | | // 滚动到底部自动追加下一页(保留手动分页跳页能力) |
| | | loadMore() { |
| | | if (this.loading || this.loadingMore) return |
| | | if (this.records.length >= this.total || this.total <= 0) return |
| | | const nextPage = this.page + 1 |
| | | this.loadingMore = true |
| | | api.get('/data/list', { |
| | | params: { |
| | | type: this.type, |
| | | period: this.period || undefined, |
| | | keyword: this.keyword || undefined, |
| | | page: nextPage, |
| | | size: this.size |
| | | } |
| | | }).then(res => { |
| | | const d = res.data || {} |
| | | const addRows = d.records || [] |
| | | if (!addRows.length) { |
| | | this.page = nextPage - 1 |
| | | return |
| | | } |
| | | this.records = this.records.concat(addRows) |
| | | this.page = nextPage |
| | | if (d.total != null) this.total = d.total |
| | | if (d.columns && d.columns.length) this.columns = d.columns |
| | | }).catch(e => { |
| | | if (e && e._toast) return |
| | | this.$message.error('加载更多失败') |
| | | }).finally(() => { |
| | | this.loadingMore = false |
| | | this.$nextTick(() => this.attachBodyScroll()) |
| | | }) |
| | | }, |
| | | onScroll(e) { |
| | | // 普通/全屏下真正的滚动容器都是 el-table 内部 body-wrapper(捕获阶段可收到); |
| | | // 页面整体滚动时以 window/document 为准。 |
| | | const t = e && e.target |
| | | let scrollTop, clientHeight, scrollHeight |
| | | if (t && t.nodeType === 1 && t !== document && typeof t.scrollTop === 'number' && t.scrollHeight > t.clientHeight) { |
| | | scrollTop = t.scrollTop |
| | | clientHeight = t.clientHeight |
| | | scrollHeight = t.scrollHeight |
| | | } else { |
| | | const se = document.scrollingElement || document.documentElement |
| | | scrollTop = se.scrollTop |
| | | clientHeight = window.innerHeight |
| | | scrollHeight = se.scrollHeight |
| | | } |
| | | if (scrollHeight > 0 && scrollTop + clientHeight >= scrollHeight - 80) { |
| | | this.loadMore() |
| | | } |
| | | }, |
| | | toggleFullscreen() { |
| | | const el = this.$refs.tableArea |
| | | const el = this.$refs.tableWrap |
| | | if (!document.fullscreenElement) { |
| | | if (el && el.requestFullscreen) el.requestFullscreen() |
| | | else this.$message.warning("浏览器不支持全屏") |
| | |
| | | if (q.period) this.period = q.period |
| | | if (q.keyword) this.keyword = q.keyword |
| | | this.loadData() |
| | | window.addEventListener('scroll', this.onScroll, { passive: true }) |
| | | if (this.$refs.tableWrap) { |
| | | // capture=true:el-table 内部 body-wrapper 的滚动在捕获阶段也能收到 |
| | | this.$refs.tableWrap.addEventListener('scroll', this.onScroll, { passive: true, capture: true }) |
| | | } |
| | | this.$nextTick(() => this.attachBodyScroll()) |
| | | }, |
| | | beforeDestroy() { |
| | | window.removeEventListener('scroll', this.onScroll) |
| | | if (this.$refs.tableWrap) { |
| | | this.$refs.tableWrap.removeEventListener('scroll', this.onScroll, { capture: true }) |
| | | const bw = this.$refs.tableWrap.querySelector('.el-table__body-wrapper') |
| | | if (bw && bw._vwScrollHandler) bw.removeEventListener('scroll', bw._vwScrollHandler) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | .el-header { background: #409EFF; color: white; line-height: 60px; font-size: 18px; } |
| | | #app .table-wrap { |
| | | display: flex; |
| | | flex-direction: column; |
| | | height: calc(100vh - 330px); |
| | | min-height: 300px; |
| | | } |
| | | #app .table-area { |
| | | flex: 1 1 auto; |
| | | min-height: 0; |
| | | overflow: hidden; |
| | | } |
| | | #app .table-area .el-table { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | #app .table-wrap .el-pagination { |
| | | flex: none; |
| | | margin-top: 8px; |
| | | } |
| | | #app .table-area:fullscreen { |
| | | padding: 20px; |
| | | background: #fff; |
| | | overflow: auto; |
| | | } |
| | | #app .table-wrap:fullscreen { |
| | | padding: 20px; |
| | | background: #fff; |
| | | overflow: auto; |
| | | display: flex; |
| | | flex-direction: column; |
| | | height: 100vh; |
| | | } |
| | | #app .table-wrap:fullscreen .table-area { |
| | | flex: 1 1 auto; |
| | | min-height: 0; |
| | | } |
| | | #app .table-wrap:fullscreen .el-pagination { |
| | | flex: none; |
| | | } |
| | | </style> |