一、前言
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就会在页面自动铺满,就像下面这样