vue中解決佈局和表格自適應的問題
阿新 • • 發佈:2018-11-29
表格自適應
我們可能在使用vue框架開發中遇到需要解決元件元素自適應的問題,如何解決呢?可以使用第三方JS庫“element-resize-detector”,並定義監聽元素變化事件的回撥函式,通過該函式動態計算元素高度,然後寫入到Vue元件的樣式中。從而實現佈局上的自適應。另外,表格的自適應原理也一致。假設我們使用iView框架裡的table元件,以表格高度自適應為例,如果我們將它的height給一個變數,而該變數正是在元素變化監聽器裡返回的,從而動態變化。考慮到效能問題,這個監聽器我們還要使用到函式節流。
由於在實際開發中,用到表格的地方不止一處,我們可以將它定義到mixins中:
// 表格高度自適應
export const tableHeight = {
// vue中元件是在mounted後才掛載到dom上的,所以在元件中我們也要在mounted後才能呼叫該方法監聽元素的大小。
mounted () {
let erd;
let $el;
// 需引入第三方js庫element-resize-detector 跨瀏覽器的調整元素的偵聽器
// 建立一個全域性函式elementResizeDetectorMaker,它是元素調整大小檢測器製造商函式的例項。
// 基於物件的方法,將在v2中刪除。
erd = elementResizeDetectorMaker();
// 採用超快速滾動方式,v2中的預設值。
// var erdUltraFast = elementResizeDetectorMaker({
// strategy: "scroll"
// });
// listenTo(element, listener)。element為偵聽resize事件的元素,listener是resize事件的監聽器函式,element會作為引數傳給listener。
erd.listenTo (this.$el, element => {
$el = element;
// 節流函式,this.setHeight在200ms內只會呼叫一次。(下面還會展開說)
util.throttle(setHeight.bind(this));
});
// 設定高度
function setHeight () {
// 表格高度為元素offsetHeight-48,其中這個offset高度為 content + padding + border 的高度。
// 一般我們獲取到表格的父元素的高度,然後把該高度給表格。
this.tableHeight = $el.offsetHeight;
}
}
};
這樣在使用到table的元件中:
引入:
import {tableHeight} from '@/mixins';
minxins中註冊:
mixins: [
tableHeight
]
在data中定義這個tableHeight並給初始值:
data() {
return {
tableHeight:100
}
}
然後我們就在html裡使用了,像這樣:
<!-- 這裡表格使用的是iView裡的table元件,分別給columns表頭和data是資料綁定了變數。而高度height屬性就要繫結的tableHeight。-->
<Table :columns="TableTitle" :data="Data" :height="tableHeight"></Table>
關於節流函式,我們可以定義在util檔案中作為工具方法,在其他mixins中引用即可。
下面展示一下供大家參考:
// 函式節流 防止連續重複呼叫
// 定義節流函式,需傳入:1.呼叫的函式 2.上下文(即呼叫傳入函式的物件)
util.throttle = function (method, context) {
// 清除時間戳
clearTimeout(method.tId);
// 定義時間戳:200ms內該函式只能被物件呼叫一次
method.tId = setTimeout(function () {
method.call(context);
}, 200);
};
佈局自適應
原理同表格,同樣利用第三方js庫’element-resize-detector’
假設在1個大盒子裡有3個小盒子。大盒子高度可變,每個小盒子裡巢狀一個iView框架裡的Collapse摺疊面板,前2個小盒子高度由內容決定,第3個小盒子高度自適應。
我們可以method中定義計算第3個小盒子自適應高度的函式:
calculatingHeight () {
// 獲取是vue元件collapse(即大盒子)上掛載的dom元素$el
let el = this.$refs.collapse.$el;
let el1 = this.$refs.collapseItem1.$el;// 第1個小盒子
let el2 = this.$refs.collapseItem2.$el;// 第2個小盒子
let erd = elementResizeDetectorMaker();
erd.listenTo(el,element => {
el = element;
util.throttle(setHeight.bind(this));
});
function setHeight () {
// 第3個小盒子的計算高度=大盒子的高度-第1個小盒子的高度-第2個小盒子的高度
this.calHeight = el.offsetHeight - el1.offsetHeight - el2.offsetHeight;
}
// 返回計算出的高度
return this.calHeight;
},
記得該方法要在mounted中呼叫:
mounted () {
this.calculatingHeight()
}
然後就可以在html中呼叫了:
<section>
<div>
<Collapse>
1.假裝有很多內容,大家感受一下,不要在意細節。css什麼的我就不寫了。
<Collapse>
</div>
<div>
<Collapse>
2.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
<Collapse>
</div>
<div>
<Collapse :style="{calHeight + 'px'}">
3.hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
<Collapse>
</div>
</section>
這裡還有其他方法解決自適應的問題,例如使用calc() 函式:
// calc() 函式用於動態計算長度值。
// calc(expression)
// expression必須,一個數學表示式,結果將採用運算後的返回值。
width: calc(100% - 100px);
// 需要注意的是,運算子前後都需要保留一個空格,例如:width: calc(100% - 10px);
// 任何長度值都可以使用calc()函式進行計算;
// calc()函式支援 "+", "-", "*", "/" 運算;
// calc()函式使用標準的數學運算優先順序規則
其他方法歡迎留言。