vue中解决布局和表格自适应的问题
表格自适应我们可能在使用vue框架开发中遇到需要解决组件元素自适应的问题,如何解决呢?可以使用第三方JS库“element-resize-detector”,并定义监听元素变化事件的回调函数,通过该函数动态计算元素高度,然后写入到Vue组件的样式中。从而实现布局上的自适应。另外,表格的自适应原理也一致。假设我们使用iView框架里的table组件,以表格高度自适应为例,如果我们将它的height.
表格自适应
我们可能在使用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()函数使用标准的数学运算优先级规则
其他方法欢迎留言。
另外,控制结构和样式时,注意从外向内,先给父级元素设定好高度,再根据父级元素给子元素设定高度这样就不会乱。尽量不要让内部元素撑开外部元素,这样很容易出问题。
前端新手,谬误之处,欢迎指正,不到之处,多多谅解。
更多推荐
所有评论(0)