iview版本: 3.5.0-rc.1
vue版本: 2.6.10
javascript
iview中的table是不能直接佔滿父容器的,它的 height
屬性必須設置成一個固定值。假如直接給table設置style爲height:100%
,它的滾動條會丟失。
html
可是不少時候咱們須要table佔滿父容器,須要表頭和頁腳進行固定,只讓中間數據部分進行滾動。vue
在 chrome
中打開 Elements
,能夠看到 iview使用了 object
標籤。 html中通常只能監聽 window
的 resize
事件,而沒法直接監聽 div
等元素大小改變的,可是有時能夠插入一個 object
標籤來間接監聽 div
大小的改變。它這裏是否用了object
來監聽大小改變呢?
打開 iview的源碼 ,看到它果然是用來監聽大小改變的,可是它監聽改變後只處理了 width
,沒有處理 height
。因此這裏咱們能夠包裝一下 Table,監聽它的resize事件,而後動態設置 height屬性,來使 Table支持 height:100%
。
java
iview是用的 element-resize-detector
庫來監聽外層div的改變,而且把將這個庫設置爲組件的全局變量。因此咱們也可使用這個全局變量來監聽外層div大小,而後動態設置 height。
git
建立一個 FillTable的組件,用來包裝 Table, FillTable.js
的源碼以下:github
import { Table } from 'iview'; export default { name: 'fill-table', render(h) { /**傳遞prop */ const tableProps = {}; for (let prop in Table.props) { tableProps[prop] = this[prop]; } tableProps.height = this.tableHeight; return h(Table, { props: tableProps, ref: 'table', /**傳遞事件 */ on: this.$listeners, /**傳遞做用域插槽 */ scopedSlots: this.$scopedSlots, /**傳遞插槽 */ slot: this.$slot }); }, props: (() => { var props = {}; Object.assign(props, Table.props, { height: { type: Number }, /** 默認佔滿父容器 */ fill: { type: Boolean, default: true } }); return props; })(), watch: { height: { handler() { this.tableHeight = this.height; } }, immediate: true }, data() { // 自帶屬性值 return { tableHeight: 0 }; }, methods: { handleIViewTableResize(el) { this.tableHeight = el.offsetHeight; }, getTableRef() { return this.$refs.table; } }, mounted() { if (this.fill) { // this.$nextTick(() => { this.getTableRef().observer.listenTo(this.$el, this.handleIViewTableResize); // }); } /**傳遞方法 */ for (let method in Table.methods) { this[method] = (...args) => Table.methods[method].apply(this.getTableRef(), args); } }, beforeDestroy() { if (this.fill) { this.getTableRef().observer.removeListener(this.$el, this.handleIViewTableResize); } } };
使用時和iview中的table的屬性和方法基本一致,只有如下地方須要注意:chrome
height:100%
的樣式。v-bind:height=固定值
,則須要 v-bind:fill="false"
getTableRef
方法,如 this.refs.table.getTableRef()
。<FillTable ref="table" style="width:100%;height:100%" :columns="columns1" :data="data1" :fill="true" > <template #name="{ row }"> <strong>{{ row.name }}--ddd</strong> </template> </FillTable>
因爲是侵入性修改,假如iview改了源碼,好比將observer的全局字段去除了,則這裏就會出錯。這時能夠直接引用 element-resize-detector
來監聽Table的大小改變。app
在線運行: https://meteor199.github.io/my-demo/vue/iview-fill-table/dist/index.html
demo源碼:https://github.com/meteor199/my-demo/tree/master/vue/iview-fill-tableiview