一、前言
el-table表格一般和搜索组件一起使用,但是有时搜索组件会有收起展开或者别的,导致table的高度并没有办法固定,那只能去动态计算。但如果说动态计算,每个页面都写,那就代码重复了。这个时候,自定义指令配合二次封装的table组件,那就完美了
二、自定义指令
vue包含一些官方指令,比如v-if、v-for、v-html、v-show等等。那如何创建一个属于自己的指令呢?自定义指令有两种,一种是全局的,一种是局部的,我这里只讲解全局的。
三、创建一个v-height
v-height,顾名思义就是计算高度的,新建一个js文件,引入vue,使用vue.directive('指令名称',xxxx)
import Vue from 'vue'
Vue.directive('height', {
bind: function(el,bind) {
// 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
},
inserted: function(el,bind) {
// 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
},
update: function(el,bind) {
// 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前
},
componentUpdated: function(el,bind) {
// 指令所在组件的 VNode 及其子 VNode 全部更新后调用
},
unbind: function(el,bind) {
// 只调用一次,指令与元素解绑时调用
}
})
钩子函数内均包含四个入参
- el:指令所绑定的元素,可以用来直接操作 DOM。
- binding:一个对象,包含以下 property:
- vnode:Vue 编译生成的虚拟节点
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
想要创建一个表格动态计算准确,首先页面高度不能坍塌,可以了解一下CSS的BFC盒模型。高度没问题后,我们只需要拿到相邻元素的高度,利用父元素高度-相邻元素高度=table组件高度 。
<template>
<div id="tableBox" v-height>
<el-table :data="tableData" height="100%" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
</div>
</template>
import Vue from 'vue'
function siblings(elm) {
var a = []; //保存所有兄弟节点
var p = elm && elm.parentNode.children; //获取父级的所有子节点
for (var i = 0; i < p.length; i++) { //循环
if (p[i].nodeType == 1 && p[i] != elm) { //如果该节点是元素节点与不是这个节点本身
a.push(p[i]); // 添加到兄弟节点里
}
}
return a;
}
Vue.directive('height', {
bind: function(el,bind) {
// 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
},
inserted: function(el,bind) {
// 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
let parentNodesH = el.parentNode.clientHeight
let nodes = document.getElementById(el.id)
let sibNodes = siblings(nodes)
let exitH = 0
sibNodes.forEach(el => {
exitH += el.clientHeight
})
el.style.height = parentNodesH - exitH + 'px'
}
})
这样,el-table就会在页面自动铺满,就像下面这样