项目技术:Vue-cli3、Element-ui、Ant-Design-Vue、Echarts4等
需求:在项目中所有使用el-table表格的地方,对【项目名称列】添加点击事件及样式【触发某个弹窗显示并在该列添加 cursor: pointer; 等样式】。
一、场景一:项目初期
1. 解决一:el-table默认插槽
描述:通过el-table默认插槽给项目名称itemName列添加指定事件及样式。
弊端:所有用到el-table的地方,都需要添加相同处理itemName列的逻辑代码。
优点:灵活性,不同表格中添加其他不同逻辑代码较灵活。
官网描述:
插槽代码:
<template slot-scope="{ row, column }">
<span
:class="{table__cellCanClick: column.property === 'iteName'}"
@click="column.property === 'iteName' && showModal()"
v-html="row[item.field]"
></span>
<span></span>
</template>
优化插槽代码(自定义指令):
let itemNameD = {
inserted: function(el, binding) {
let row = binding.value.row;
let column = binding.value.column;
if (column.property === "itemName") {
el.classList.add("table__cell-can-click");
el.addEventListener("click", () => {
console.log(row);
});
}
}
};
Vue.directive("itemNameD", itemNameD);
<template>
<!-- 省略部分多余代码 -->
<el-table>
<template slot-scope="{ row, column }">
<span v-itemNameD="{ row, column }">{{ row[item.field] }}</span>
</template>
</el-table>
</template>
2. 解决二:同场景二的解决一
二、场景二:项目后期
描述:整个项目直接使用el-table组件的地方有近百处,秉承尽可能的减少修改原代码原则。
解决一:私有化el-table组件
描述:私有化掉el-table组件 然后去改这个组件 组件内部进行调整。最后在项目中覆盖掉element的el-table组> 件。
缺点:当更新element-ui的版本后,还需要重写el-table。
优点:不用修改项目原来代码,毕竟使用到的地方近百个el-table。
对源码有抵触心理的,可以先通过这篇简单了解 # element-ui 的组件源码还能这么看:
-
找到el-table的源码 node_module/element-ui/packages/table 整个文件复制到项目中(不要被eslent检测到,尽可能少改动源码) -
修改依赖 因为项目中使用Vue.use(ElementUI); 将element组件全部注册,将代码中引入组件 element-ui/packages 的代码注释掉(如果不注释掉会报错,直接引入node_module下element-ui/packages下的单个组件,可能内部代码在未显示引入全局Vue的情况下,不能直接使用Vue的transition等组件),默认直接使用Vue全局组件即可,以table-body.js 为例: -
添加逻辑代码 一步步简略查看最终定位到 src/table-body.js : created() {
this.selfCustomField = ['itemName'];
},
methods: {
rowRender(row, $index, treeRowData) {
return (
<td
style={ this.getCellStyle($index, cellIndex, row, column) }
class={ this.getCellClass($index, cellIndex, row, column) }
rowspan={ rowspan }
colspan={ colspan }
on-click={ ($event) => this.handleCellClick($event, row, column) }
on-mouseenter={ ($event) => this.handleCellMouseEnter($event, row) }
on-mouseleave={ this.handleCellMouseLeave }>
{
column.renderCell.call(
this._renderProxy,
this.$createElement,
data,
columnsHidden[cellIndex]
)
}
</td>
);
},
getCellClass(rowIndex, columnIndex, row, column) {
if (this.selfCustomField.includes(column.property)) {
classes.push('table__cell-can-click');
}
classes.push('el-table__cell');
return classes.join(' ');
}
handleCellClick(event, row, column) {
if (this.selfCustomField.includes(column.property)) {
console.log(row);
}
},
}
-
在main.js中覆盖原el-table组件 import ElementUI from "element-ui";
import ElTable from "./components/ReWriteFrameComponents/el-table";
Vue.use(ElementUI);
Vue.use(ElTable);
最终效果:
解决二:识别并修改Vnode
描述:识别router-view当前route中内部所有el-table,并修改Vnode。 目前个人能力有限,暂且搁置,后面会进行补充。
|