携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情
分析
在 handsontable插件的详细使用方法 中,我们说过如果 handsontable 插件绑定的数据结构为对象数组形式,那么表格的右键菜单栏中对于列的操作将失效。但是在项目中,我们并不能够避免不使用对象数组,所以既然不能使用菜单面板中的操作项,那么我们可以用其他的办法来达到相同的效果,通过分析 handsontable 插件的使用方式,可以知道,该表格插件的实现无非就是有以下几点:
- 绑定数据(data:对象数组形式的数据)
- 设置表头(colHeaders)
- 设置表格列(columns)
- 其他的配置项
那么其实我们只需要改变 data、colHeaders、columns 就可以实现增加和删除列的操作了。
实现
HTML
页面结构渲染,在这里主要增加了“新增列”和“删除列”两个按钮来实现我们要的功能。
<template>
<div class="app-container">
<div style="margin-bottom: 10px">
<el-button size="small" type="success" @click="addCombVaribles">新增列</el-button>
<el-select
v-model="selectedColumn"
placeholder="请选择"
style="width: 15%; margin: 0 10px"
>
<el-option
v-for="(option_item, i) in hotSettings.colHeaders"
:key="i"
:label="option_item"
:value="option_item"
:disabled="i === 0 ? true : false"
/>
</el-select>
<el-button
size="small"
type="danger"
:disabled="selectedColumn === '' ? true : false"
@click="removeCombVaribles"
>删除列</el-button>
</div>
<HotTable ref="hotTableComponent2" :settings="hotSettings" />
</div>
</template>
JS
js中的操作主要有以下几点:
- 引入插件资源(import)
- 注册插件组件(components)
- 插件需渲染的数据(excelData2)
- 下拉框选中的需要删除的列名(selectedColumn)
- 插件配置项(hotSettings)
- 数据初始化加载(created)
- 增加列功能实现的方法(addCombVaribles)
- 删除列功能实现的方法(removeCombVaribles)
<script>
import { HotTable } from "@handsontable/vue";
import Handsontable from 'handsontable'
import "handsontable/languages"; // 语言设置
import "../../../../node_modules/handsontable/dist/handsontable.full.css"; // 样式
export default {
name: "App",
components: {
HotTable,
},
data() {
return {
selectedColumn: "",
excelData2: [
{
column0: 1,
column1: "EUR",
column2: "Euro",
column3: 0.9033,
column4: "EUR / USD",
column5: "08/19/2019",
column6: 0.0026,
},
{
column0: 2,
column1: "JPY",
column2: "Japanese Yen",
column3: 124.387,
column4: "JPY / USD",
column5: "08/19/2019",
column6: 0.0001,
},
{
column0: 3,
column1: "GBP",
column2: "Pound Sterling",
column3: 0.6396,
column4: "GBP / USD",
column5: "08/19/2019",
column6: 0.0,
},
],
hotSettings: {
language: 'zh-CN', // 语言设置
licenseKey: 'non-commercial-and-evaluation', // 隐藏版权文字
width: 'auto', // 表格宽度
height: '400', // 表格高度、设置以后才会出现scroll
data: [],
startRows: 1, // 初始化行数,无data属性时生效(该值小于minRows时,以minRows为准)
startCols: 2, // 初始化列数,无data属性时生效(该值小于minCols时,以minCols为准)
minRows: 1, // 最少行数(当初始化数据小于该值时,以该值为准)
minCols: 2, // 最少列数(当初始化数据小于该值时,以该值为准)
minSpareCols: 0, // 列的最小留白数
minSpareRows: 0, // 行的最小留白数
colHeaders: [
"column0",
"column1",
"column2",
"column3",
"column4",
"column5",
"column6",
], // 是否展示列表头,默认是A,B,C等字母,可以['列1','列2']进行自定义展示
rowHeaders: true, // 是否展示行表头,默认是1,2,3等数据,可以['行1','行2']进行自定义展示
columns: [
{
data: "column0",
},
{
data: "column1",
},
{
data: "column2",
},
{
data: "column3",
},
{
data: "column4",
},
{
data: "column5",
},
{
data: "column6",
},
],
// colWidths: 205, // 列宽度
stretchH: 'all', // 自适应列宽,默认值none,last 将最后一列拉伸到最大,all 将所有列均匀拉伸
dropdownMenu: false, // 表头展示下拉菜单,可以自定义展示
className: 'htCenter', // 单元格文字对齐方式(htLeft,htRight,htCenter)
currentRowClassName: 'my-selectRow', // 给选中行添加自定义class类名
currentColClassName: 'my-selectCol', // 给选中列添加自定义class类名
autoWrapRow: true, // 文字是否自动换行(当没有设置colWidths时生效)
fixedRowsTop: 0, // 列表内容从上面开始,固定定位的行数(不包含行表头)
fixedColumnsLeft: 1, // 列表内容从左面开始,固定定位的列数(不包含列表头)
fillHandle: true, // 是否开启拖拽复制操作(true,false,'horizontal'水平复制,'vertical'垂直复制)
trimWhitespace: true, // 过滤掉空格
contextMenu: { // 单元格右击展示菜单
items: {
col_left: {
name: '左侧插入一列'
},
col_right: {
name: '右侧插入一列'
},
remove_col: {
name: '移除本列'
},
alignment: {
name: '对齐方式'
},
make_read_only: {
name: '只读'
},
copy: {
name: '复制'
},
cut: {
name: '剪切'
},
separator: Handsontable.plugins.ContextMenu.SEPARATOR,
clear_custom: {
name: '清空所有单元格数据',
callback: function() {
this.clear()
}
}
}
}
},
};
},
created() {
// 所有 Dom 渲染完才能拿到ref组件里的属性
this.$nextTick(function() {
this.$refs.hotTableComponent2.hotInstance.loadData(this.excelData2)
})
},
methods: {
addCombVaribles() {
var excelData1 = this.$refs.hotTableComponent2.hotInstance.getData();
var num = Number(this.hotSettings.colHeaders[this.hotSettings.colHeaders.length - 1].replace("column", "")) + 1;
this.hotSettings.colHeaders.push("column" + num);
this.hotSettings.columns.push({
data: "column" + num,
});
var excelData2 = [];
for (var i = 0; i < excelData1.length; i++) {
excelData2.push({});
for (var index in this.hotSettings.colHeaders) {
if (Number(index) < excelData1[i].length) {
excelData2[i][this.hotSettings.colHeaders[index]] = excelData1[i][index];
} else {
excelData2[i][this.hotSettings.colHeaders[index]] = null;
}
}
}
// 所有 Dom 渲染完才能拿到ref组件里的属性
this.$nextTick(function () {
this.$refs.hotTableComponent2.hotInstance.loadData(excelData2);
});
},
removeCombVaribles() {
var excelData1 = this.$refs.hotTableComponent2.hotInstance.getData();
this.hotSettings.colHeaders.splice(this.hotSettings.colHeaders.indexOf(this.selectedColumn), 1);
for (var index1 in this.hotSettings.columns) {
if (this.hotSettings.columns[index1]["data"] === this.selectedColumn) {
this.hotSettings.columns.splice(index1, 1);
for (var i = 0; i < excelData1.length; i++) {
excelData1[i].splice(index1, 1);
}
break;
}
}
var excelData2 = [];
for (var j = 0; j < excelData1.length; j++) {
excelData2.push({});
for (var index in this.hotSettings.colHeaders) {
excelData2[j][this.hotSettings.colHeaders[index]] = excelData1[j][index];
}
}
// 所有 Dom 渲染完才能拿到ref组件里的属性
this.$nextTick(function () {
this.$refs.hotTableComponent2.hotInstance.loadData(excelData2);
});
this.selectedColumn = "";
},
},
};
</script>