@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>
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago