1. 程式人生 > >vue中解決佈局和表格自適應的問題

vue中解決佈局和表格自適應的問題

表格自適應

我們可能在使用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()函式使用標準的數學運算優先順序規則

其他方法歡迎留言。

另外,控制結構和樣式時,注意從外向內,先給父級元素設定好高度,再根據父級元素給子元素設定高度這樣就不會亂。儘量不要讓內部元素撐開外部元素,這樣很容易出問題。

前端新手,謬誤之處,歡迎指正,不到之處,多多諒解。