@junhe/common-table v1.0.27
使用前准备
要确保项目中使用的 Vue2 版本为 2.6.14,步骤如下:
在 package.json 中:
"vue": "^2.6.14" 改为 "vue": "2.6.14",
"vue-template-compiler": "^2.6.14" 改为 "vue-template-compiler": "2.6.14"
然后删除项目中的 node_modules 和 package-lock.json
最后重新安装一下依赖:npm install
使用说明书(FlexibleTableIntegration.vue)
外部可以调用的方法
refreshTableRows 刷新表格内容数据
resetCurrPageAndRefreshTableRows 重置当前页码到第一页,并刷新表格内容数据
addFormRow 添加一行新的表单行
addNewRows 添加一或多行新的普通数据行
getRowMultiSelection 获取所有被多选列勾选的数据
setRowMultiSelection 设置多选列的选中状态
getRowSingleSelection 获取被单选列选中的数据
setRowSingleSelection 设置单选列的选中状态
对外抛出的事件
cell-click 当表格的可点击单元格被点击时
column-button-click 当表格中的图标列的单元格被点击时
cell-corner-tip-click 当表格的单元格右上角的提示性按钮被点击时
row-multi-select 当多选列的选中状态被改变时
text-search 当搜索框有改变并确认时
selection-list-change 当筛选栏的当前筛选器的筛选项被选中或取消时
Props
属性名 | 解释 |
---|---|
baseURL | 后端地址(指定本值,主要用于测试用途) |
normalTabs | 标签列表 |
extraTabs | 不显示本页内容的标签 |
defaultTabIndex | 默认显示的标签的序号 |
operationWidth | 操作按钮列的宽度 |
cardWidth | 卡片视图下卡片的宽度 |
moduleName | 模块名称(传给后端) |
hasDataOverview | 是否有数据概览 |
hasClassification | 是否有标签栏 |
defaultFilterIndex | 默认打开第几个单列条件选择器(从0开始) |
hasCheckboxColumn | 是否有多选列 |
isSelectionReserved | 换页时,是否保持之前的选择 |
hasDataStatistics | 是否有统计数据 |
hasExportData | 是否有导出表格数据的功能按钮 |
hasOperation | 是否有操作按钮 |
hasViewSwitcher | 是否有表格视图和卡片视图的切换功能 |
hasSideFilter | 是否有侧边筛选栏 |
formCellUpdateType | 表格型单元格的更新类型 |
defaultView | 默认的视图 |
confirmCellSelection | 表格中的下拉框单元格的下拉列表的某一项被选中时的回调 |
使用方法示例
<template>
<div class="test-flexible-table">
<div class="module-btns">
<ElButton
:type="moduleName === '模块1' ? 'primary' : 'default'"
size="mini"
@click="onModuleBtnClick(1)"
>模块1</ElButton
>
<ElButton
:type="moduleName === '模块2' ? 'primary' : 'default'"
size="mini"
@click="onModuleBtnClick(2)"
>模块2</ElButton
>
</div>
<div class="flexible-table-container">
<FlexibleTableIntegration
ref="flexibleTableIntegration"
:baseURL="baseURL"
:normalTabs="NORMAL_TABS"
:extraTabs="EXTRA_TABS"
:defaultTabIndex="DEFAULT_TAB_INDEX"
:operationWidth="100"
:cardWidth="300"
:moduleName="moduleName"
:hasDataOverview="false"
:hasClassification="false"
:defaultFilterIndex="2"
:hasCheckboxColumn="isMultiSelection"
:hasRadioColumn="!isMultiSelection"
:isSelectionReserved="true"
:hasExportData="true"
:hasOperation="true"
:hasViewSwitcher="true"
:hasSideFilter="true"
:defaultSideFilterVisible="true"
:defaultView="'table'"
:confirmCellSelection="confirmCellSelection"
@cell-click="onBodyCellClick"
@cell-corner-tip-click="onBodyCellCornerTipClick"
@column-button-click="onColumnButtonClick"
@row-multi-select="onRowMultiSelect"
>
<template v-slot:operation="row">
<OperationButton
:name="'op1'"
:title="'操作1'"
:row="row"
:hasIcon="true"
:maxTitleCount="3"
@btn-click="onOperationBtnClick"
>
<!-- <template v-slot:icon>
<IconFilter :size="12" />
</template> -->
</OperationButton>
<!-- <OperationDropdown>
<OperationDropdownItem
:name="'op4'"
:title="'操作4'"
:row="row"
:hasIcon="false"
@item-click="onOperationBtnClick"
></OperationDropdownItem>
<OperationDropdownItem
:name="'op5'"
:title="'操作5'"
:row="row"
:hasIcon="true"
@item-click="onOperationBtnClick"
>
<template v-slot:icon>
<IconFilter :size="12" />
</template>
</OperationDropdownItem>
<OperationDropdownItem
:name="'op6'"
:title="'操作6'"
:row="row"
:hasIcon="true"
@item-click="onOperationBtnClick"
>
<template v-slot:icon>
<IconFilter :size="12" />
</template>
</OperationDropdownItem>
</OperationDropdown> -->
</template>
<template v-slot:midbar>
<ElSwitch
:style="{ width: '132px' }"
v-model="isMultiSelection"
active-text="多选"
inactive-text="单选"
>
</ElSwitch>
<ElButton type="primary" size="small" @click="onGetSelectClick"
>获取选择</ElButton
>
<ElButton type="primary" size="small" @click="onSetSelectClick"
>尝试选择</ElButton
>
</template>
11
<template v-slot:card="{ row }">
<CardTemplate
class="my-card"
:height="200"
:imgSrc="'https://youimg1.c-ctrip.com/target/100r10000000pycel4E0E.jpg'"
>
<template v-slot:header>{{ row["type_row_id"] }}</template>
<template v-slot:details>
<div class="rows">
<div class="row">
<span>{{ row["type_string2"] }}</span>
</div>
<OverflowTooltip :content="row['type_string']">
<div class="row">
<span>{{ row["type_string"] }}</span>
</div>
</OverflowTooltip>
<div class="row">
<span>{{ row["type_merge_str"] }}</span>
</div>
</div>
</template>
</CardTemplate>
</template>
<template v-slot:button-column-icon="{ iconClass, data }">
<template v-if="iconClass === 'plus'">
<IconAdd />
</template>
<template v-else-if="iconClass === 'copy'">
<IconCopy />
</template>
<template v-else-if="iconClass === 'edit'">
<IconEdit />
</template>
<template v-else-if="iconClass === 'comment-btn'">
<IconComment />
</template>
<template v-else-if="iconClass === 'receivable-node-btn'">
<template v-if="Array.isArray(data)">
<template v-for="(node, index) in data">
<IconTextCircle
:key="index"
:text="node['name']"
:active="node['active']"
/>
</template>
</template>
</template>
<template v-else-if="iconClass === 'alert-btn'">
<IconAlertSign :text="'已有风险'" />
<!-- <template v-for="(node, index) in data">
</template> -->
</template>
<template v-else></template>
</template>
<!-- <template v-slot:cell-bottom="{ row, col }">
<div
class="my-progress-bar"
v-if="col.id === 'type_number' && row['type_row_id']"
>
<el-progress
:text-inside="true"
:stroke-width="8"
:percentage="70"
></el-progress>
</div>
</template> -->
<!-- <template v-slot:cell-left="{ row, col }">
<div
class="my-tip"
v-if="col.id === 'type_number' && row['type_row_id']"
></div>
</template> -->
<template v-slot:form-cell="{ row, col }">
<template v-if="col.id === 'icon_col_1'">
<div class="my-form-cell">
<template v-if="typeof row[col.id] === 'string'">
<div class="my-column-icon" :style="{ cursor: 'pointer' }">
<Icon
:size="24"
:iconBaseUrl="row[col.id]"
@click.native="onFormCellBtnEditClick(row, col)"
/>
</div>
</template>
<template v-else>
<ElButton
type="text"
size="mini"
@click="onFormCellBtnEditClick(row, col)"
>自定义功能</ElButton
>
</template>
</div>
</template>
</template>
</FlexibleTableIntegration>
</div>
<ElDialog
class="my-dial-icon-selection"
title="提示"
:visible.sync="isIconDialVisible"
width="30%"
>
<div class="content">
<div :style="{ marginBottom: '16px' }">在此选择头像</div>
<div>
<template v-for="(url, index) in iconUrls">
<Icon
class="user-icon"
:style="{ cursor: 'pointer', marginRight: '16px' }"
:key="index"
:iconBaseUrl="url"
@click.native="onDialIconClick(url)"
/>
</template>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="isIconDialVisible = false">取 消</el-button>
<el-button type="primary" @click="isIconDialVisible = false"
>确 定</el-button
>
</span>
</ElDialog>
</div>
</template>
<script>
import Vue from "vue";
import {
Button as ElButton,
// Progress as ElProgress,
Dialog as ElDialog,
Switch as ElSwitch,
} from "element-ui";
import {
FlexibleTableIntegration,
CardTemplate,
OperationButton,
// OperationDropdown,
// OperationDropdownItem,
OverflowTooltip,
Icon,
IconAdd,
IconCopy,
IconEdit,
IconComment,
IconTextCircle,
IconAlertSign,
// IconFilter,
// BaseColumn,
// Column,
ButtonColumn,
// IconColumn,
// KeyValuePair,
} from "@junhe/common-table";
const NORMAL_TABS = [
{ name: "tab-name-1", label: "标签1" },
{ name: "tab-name-2", label: "标签2" },
{ name: "tab-name-3", label: "标签3" },
];
const EXTRA_TABS = [{ name: "board", label: "看板" }];
const DEFAULT_TAB_INDEX = 0;
export default Vue.extend({
name: "TestWithFakeData",
components: {
ElButton,
// ElProgress,
ElDialog,
ElSwitch,
IconAdd,
IconCopy,
IconEdit,
IconComment,
IconTextCircle,
IconAlertSign,
// IconFilter,
FlexibleTableIntegration,
CardTemplate,
OperationButton,
// OperationDropdown,
// OperationDropdownItem,
OverflowTooltip,
Icon,
},
data() {
return {
moduleName: "模块1",
NORMAL_TABS,
EXTRA_TABS,
DEFAULT_TAB_INDEX,
baseURL: "http://220.168.85.72:10930",
// baseURL: "http://localhost:10930",
isIconDialVisible: false,
iconUrls: [
"http://220.168.85.72:3000/avatars/d73d86c441955bd24b89577835608fa3?size=512",
"http://220.168.85.72:3000/avatars/e47e9a540465ff1cc530b46afa573c6e?size=512",
],
currCellInfo: {
row: {},
col: {},
},
isMultiSelection: false, // 是显示多选列还是单选列
};
},
computed: {
iconStyle() {
const size = 12;
return { width: `${size}px`, height: `${size}px` };
},
},
methods: {
onModuleBtnClick(flag) {
this.moduleName = `模块${flag}`;
},
// 表格操作列中的某个按钮被点击
onOperationBtnClick(row, name) {
console.log("row, name :>> ", row, name);
},
// 当表格的可点击单元格被点击时
onBodyCellClick(row, col) {
console.log("row, col :>> ", row, col);
},
// 当表格中的图标列的单元格被点击时
onColumnButtonClick(row, col, insideBtnCol) {
const refTb = this.$refs["flexibleTableIntegration"];
if (col instanceof ButtonColumn) {
// 属于独立按钮列
switch (col.iconClass) {
case "comment-btn": {
// 复制一遍 row,然后添加到表格中
const newRow = JSON.parse(JSON.stringify(row));
newRow.id = `id-${Math.random()}`;
newRow.type_merge_str = `${Math.floor(Math.random() * 1000)}`;
refTb.addNewRows(row, [newRow]);
break;
}
case "receivable-node-btn": {
console.log("receivable-node-btn", row);
break;
}
default:
break;
}
} else {
// 属于内置按钮列
switch (insideBtnCol.iconClass) {
case "plus": {
refTb.addFormRow(row, "new", {
submissionExceptionClassNames: ["my-dial-icon-selection"],
});
break;
}
case "copy": {
refTb.addFormRow(row, "copy", {
submissionExceptionClassNames: ["my-dial-icon-selection"],
});
break;
}
default:
break;
}
}
},
// 当表格的单元格右上角的提示性按钮被点击时
onBodyCellCornerTipClick(row, col) {
console.log("row, col :>> ", row, col);
},
// 当多选列的选中状态被改变时
onRowMultiSelect(selection) {
console.log("selection :>> ", selection);
},
/**
* 表格中的下拉框单元格 -> 下拉列表的某一项被选中时的回调
* @param resolve resolve(true) 代表确认选择,resolve(false) 代表取消选择
*/
confirmCellSelection(row, column, item, resolve) {
console.log("row, column, item :>> ", row, column, item);
setTimeout(() => {
resolve(true);
}, 1000);
},
onGetSelectClick() {
const refTb = this.$refs["flexibleTableIntegration"];
let selection;
if (this.isMultiSelection) {
selection = refTb.getRowMultiSelection();
} else {
selection = refTb.getRowSingleSelection();
}
console.log("当前选择的行 :>> ", selection);
},
onSetSelectClick() {
const refTb = this.$refs["flexibleTableIntegration"];
if (this.isMultiSelection) {
refTb.setRowMultiSelection(["id-2", "id-3"]);
} else {
refTb.setRowSingleSelection("id-2");
}
},
onFormCellBtnEditClick(row, col) {
console.log("col :>> ", col);
this.currCellInfo = { row, col };
this.isIconDialVisible = true;
},
onDialIconClick(url) {
const { row, col } = this.currCellInfo;
if (row && col) {
console.log("row, col :>> ", row, col);
row[col.id] = url;
}
},
},
});
</script>
<style lang="scss" scoped>
.test-flexible-table {
width: 100%;
height: 100%;
$module-btns-height: 32px;
.module-btns {
box-sizing: border-box;
width: 100%;
height: $module-btns-height;
border-bottom: 1px solid #eee;
}
.flexible-table-container {
box-sizing: border-box;
width: 100%;
height: calc(100% - $module-btns-height);
}
.my-progress-bar {
width: 100%;
}
.my-card {
.rows {
box-sizing: border-box;
width: 100%;
height: 100%;
padding: 8px 0;
.row {
width: 100%;
height: 28px;
line-height: 28px;
}
}
}
.my-form-cell {
.my-column-icon {
}
}
.my-dial-icon-selection {
}
}
</style>
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago
12 months ago