表格自适应

我们可能在使用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()函数使用标准的数学运算优先级规则

其他方法欢迎留言。

另外,控制结构和样式时,注意从外向内,先给父级元素设定好高度,再根据父级元素给子元素设定高度这样就不会乱。尽量不要让内部元素撑开外部元素,这样很容易出问题。
前端新手,谬误之处,欢迎指正,不到之处,多多谅解。
Logo

前往低代码交流专区

更多推荐