mirror of https://gitee.com/lmlz_0/dc-ui.git
eric777
10 months ago
22 changed files with 2480 additions and 685 deletions
@ -0,0 +1,653 @@ |
|||
<template> |
|||
<vxe-grid |
|||
ref="tableRef" |
|||
v-bind="gridOptions" |
|||
:loading="props.loading" |
|||
:columns="props.columns" |
|||
:data="props.tableData" |
|||
@cell-dblclick="cellDBLClickEvent" |
|||
:row-style="getRowStyle" |
|||
@edit-actived="onEditActivated" |
|||
@page-change="pageChange" |
|||
> |
|||
<template #toolbar_buttons> |
|||
<vxe-button size="small" status="primary" icon="vxe-icon-add" @click="addRow()" v-if="hasAddRows"> |
|||
{{ addRowsText }} |
|||
</vxe-button> |
|||
<vxe-button size="small" status="danger" icon="vxe-icon-delete-fill" @click="delSelect" v-if="hasDelSelect"> |
|||
删除 |
|||
</vxe-button> |
|||
<vxe-button size="small" status="success" icon="vxe-icon-save" @click="allSave" v-if="props.hasAllSave"> |
|||
保存 |
|||
</vxe-button> |
|||
</template> |
|||
<template #toolbar_buttons_new> |
|||
<vxe-button size="small" status="primary" icon="vxe-icon-add" @click="addRow()" v-if="hasAddRows"> |
|||
{{ addRowsText }} |
|||
</vxe-button> |
|||
<vxe-button size="small" status="danger" icon="vxe-icon-delete-fill" @click="delSelect" v-if="hasDelSelect"> |
|||
删除 |
|||
</vxe-button> |
|||
</template> |
|||
<template #statusDef="{ row }"> |
|||
<vxe-switch v-model="row.status" size="mini"></vxe-switch> |
|||
</template> |
|||
<template #text="{ row, column }"> |
|||
<el-input |
|||
@mousedown.stop |
|||
v-model="row[column?.field]" |
|||
placeholder="请输入内容" |
|||
disabled |
|||
/> |
|||
</template> |
|||
<template #input="{ row, column }"> |
|||
<el-input |
|||
@mousedown.stop |
|||
v-model="row[column?.field]" |
|||
placeholder="请输入内容" |
|||
/> |
|||
</template> |
|||
<template #treeSelect="{ row, column }"> |
|||
<el-tree-select |
|||
@mousedown.stop |
|||
v-model="row[column?.field]" |
|||
:data="typeof column.slots.data === 'function' ? column.slots.data(row,column) : column.slots.data" |
|||
:props="column.slots.props" |
|||
check-strictly |
|||
:default-expand-all="true" |
|||
:value-key="column.slots.key" |
|||
:size="column.slots.size" |
|||
@change="($event) => { column.slots.change($event, row, column)}" |
|||
/> |
|||
</template> |
|||
<template #select="{ row, column }"> |
|||
<el-select @mousedown.stop v-model="row[column?.field]" @change="column?.slots.change($event,row,column)" :disabled="column?.slots.disabled" :filterable="column?.slots.filterable" @visible-change="column?.slots.visibleChange($event,row,column)"> |
|||
<el-option v-for="dict in column?.slots.options" :key="dict[column?.slots.key]" :label="dict[column?.slots.label]" |
|||
:value="dict[column?.slots.value]" /> |
|||
</el-select> |
|||
</template> |
|||
<template #operate="{$table, row, column }"> |
|||
<template v-if="hasEditRows(row)"> |
|||
<vxe-button size="small" type="text" content="取消" icon="vxe-icon-close" @click="cancelRowClick"></vxe-button> |
|||
<vxe-button size="small" type="text" status="primary" content="保存" icon="vxe-icon-check" |
|||
@click="saveRowClick(row)"></vxe-button> |
|||
</template> |
|||
<template v-else> |
|||
<vxe-button v-if="getButtonShow($table,row,'newButton')" size="small" type="text" :content="getButtonInfo($table,row,'name','newButton')" icon="vxe-icon-edit" @click="getButtonInfo($table,row,'btn','newButton')"></vxe-button> |
|||
<vxe-button v-if="getButtonShow($table,row,'newButtonTwo')" size="small" type="text" :content="getButtonInfo($table,row,'name','newButtonTwo')" icon="vxe-icon-edit" @click="getButtonInfo($table,row,'btn','newButtonTwo')"></vxe-button> |
|||
<vxe-button size="small" type="text" content="编辑" icon="vxe-icon-edit" v-if="hasEditRow" |
|||
@click="editRowClick(row)"></vxe-button> |
|||
</template> |
|||
<vxe-button size="small" type="text" status="danger" content="删除" icon="vxe-icon-delete" v-if="hasdelRow" |
|||
@click="delRowClick(row)"></vxe-button> |
|||
</template> |
|||
<template #operateNew="{$table, row, column }"> |
|||
<template v-if="hasEditRows(row)"> |
|||
<vxe-button size="small" type="text" content="取消" icon="vxe-icon-close" @click="cancelRowClick"></vxe-button> |
|||
<vxe-button size="small" type="text" status="primary" content="保存" icon="vxe-icon-check" |
|||
@click="saveRowClick(row)"></vxe-button> |
|||
</template> |
|||
<template v-else> |
|||
<vxe-button v-if="getButtonShow($table,row,'newButton')" size="small" type="text" :content="getButtonInfo($table,row,'name','newButton')" icon="vxe-icon-edit" @click="getButtonInfo($table,row,'btn','newButton')"></vxe-button> |
|||
<vxe-button v-if="getButtonShow($table,row,'newButtonTwo')" size="small" type="text" :content="getButtonInfo($table,row,'name','newButtonTwo')" icon="vxe-icon-edit" @click="getButtonInfo($table,row,'btn','newButtonTwo')"></vxe-button> |
|||
<vxe-button size="small" type="text" content="编辑" icon="vxe-icon-edit" v-if="hasEditRow" |
|||
@click="editRowClick(row)"></vxe-button> |
|||
</template> |
|||
<vxe-button size="small" type="text" status="danger" content="删除" icon="vxe-icon-delete" v-if="hasdelRow" |
|||
@click="delRowClick(row)"></vxe-button> |
|||
</template> |
|||
</vxe-grid> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { reactive,defineExpose } from "vue"; |
|||
import { VXETable } from "vxe-table"; |
|||
const { proxy } = getCurrentInstance(); |
|||
const tableRef = ref(); |
|||
const tableHeight = ref('0px'); |
|||
const rowHeight = ref(44); |
|||
const headerHeight = ref(66); |
|||
const emit = defineEmits([ |
|||
"insertRecords", |
|||
"updateRecords", |
|||
"delSelectData", |
|||
"allSaveRowData", |
|||
"saveRowData", |
|||
"delRowData", |
|||
"btnClick", |
|||
"cellDBLClick", |
|||
"pageChange", |
|||
"beforeEditRowsCallBack", |
|||
"validateFormMethod", |
|||
"beforeAddRowsCallBack", |
|||
"addRowsCallBack", |
|||
]); |
|||
|
|||
const props = defineProps({ |
|||
config: { |
|||
//表格配置项 |
|||
type: Object, |
|||
default: { |
|||
//表格配置项 |
|||
id: "table", //唯一标识 |
|||
height: "auto", //表格的高度;支持铺满父容器或者固定高度 |
|||
align: "center", //所有的列对齐方式 |
|||
border: "none", //是否带有边框:false|default 默认显示边框,true|full 显示完整边框,outer 显示外边框,inner 显示内边框,none |
|||
round: true, //是否为圆角边框 |
|||
stripe: true, //是否带有斑马纹 |
|||
size: "medium", //表格的尺寸:medium, small, mini |
|||
// loading: false, //表格是否显示加载中 |
|||
showHeader: true, //是否显示表头 |
|||
columnConfig: { |
|||
//列配置信息 |
|||
isCurrent: false, //当鼠标点击列头时,是否要高亮当前列 |
|||
isHover: true, //当鼠标移到列头时,是否要高亮当前头 |
|||
}, |
|||
rowConfig: { |
|||
//行配置信息 |
|||
keyField: "id", //自定义行数据唯一主键的字段名 |
|||
isCurrent: false, //当鼠标点击行时,是否要高亮当前行 |
|||
isHover: true, //当鼠标移到行时,是否要高亮当前行 |
|||
}, |
|||
editConfig: { |
|||
//可编辑配置项 |
|||
trigger: "dblclick", //触发方式click(点击触发编辑),dblclick(双击触发编辑) |
|||
mode: "row", //编辑模式cell(单元格编辑模式),row(行编辑模式) |
|||
}, |
|||
pagerConfig: { |
|||
//分页配置项 |
|||
enabled: true, //是否启用 |
|||
currentPage: 1, //当前页 |
|||
pageSize: 10, //每页大小 |
|||
total: 0, //总条数 |
|||
autoHidden: true, //当只有一页时自动隐藏 |
|||
pageSizes: [10, 15, 20, 50, 100], //每页大小选项列表 |
|||
}, |
|||
toolbarConfig: { |
|||
//工具栏配置 |
|||
refresh: true, // 显示刷新按钮 |
|||
import: false, // 显示导入按钮 |
|||
export: false, // 显示导出按钮 |
|||
zoom: true, // 显示全屏按钮 |
|||
custom: true, // 显示自定义列按钮 |
|||
}, |
|||
}, |
|||
}, |
|||
colField: { |
|||
//新增时默认可编辑字段 |
|||
type: String, |
|||
default: "", |
|||
}, |
|||
additional: { |
|||
//新增时增加默认显示字段 |
|||
type: Object, |
|||
default: {}, |
|||
}, |
|||
columns: { |
|||
//表格表头数据 |
|||
type: Array, |
|||
default: [], |
|||
}, |
|||
tableData: { |
|||
//表格数据 |
|||
type: Array, |
|||
default: [], |
|||
}, |
|||
loading: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
addRowsText: { |
|||
//新增按钮文字 |
|||
type: String, |
|||
default: "新增", |
|||
}, |
|||
addRowsType: { |
|||
//新增按钮类型,1新增功能,2纯按钮用于其他操作 |
|||
type: Number, |
|||
default: 1, |
|||
}, |
|||
hasAddRows: { |
|||
//是否显示新增按钮 |
|||
type: Boolean, |
|||
default: true, |
|||
}, |
|||
hasDelSelect: { |
|||
//是否显示删除按钮 |
|||
type: Boolean, |
|||
default: true, |
|||
}, |
|||
hasAllSave: { |
|||
//是否显示保存 |
|||
type: Boolean, |
|||
default: true, |
|||
}, |
|||
hasEditRow: { |
|||
//是否显示操作编辑按钮 |
|||
type: Boolean, |
|||
default: true, |
|||
}, |
|||
hasdelRow: { |
|||
//是否显示操作删除按钮 |
|||
type: Boolean, |
|||
default: true, |
|||
}, |
|||
pagination: { |
|||
//分页 |
|||
type: Object, |
|||
default: { |
|||
total: 0, |
|||
currentPage: 1, |
|||
pageSize: 10, |
|||
}, |
|||
}, |
|||
}); |
|||
const { config, colField, addRowsType, hasAddRows, hasDelSelect } = props; |
|||
|
|||
const gridOptions = reactive({ |
|||
id: config.id, //唯一标识 |
|||
height: tableHeight, //表格的高度;支持铺满父容器或者固定高度 |
|||
maxHeight: config.maxHeight, |
|||
minHeight: 200, //最小高度 |
|||
autoResize: true, //自动监听父元素的变化去重新计算表格 |
|||
align: config.align, //所有的列对齐方式 |
|||
border: config.border, //是否带有边框 |
|||
round: config.round, //是否为圆角边框 |
|||
stripe: config.stripe, //是否带有斑马纹 |
|||
size: config.size, //表格的尺寸:medium, small, mini |
|||
// loading: config.loading, //表格是否显示加载中 |
|||
showHeader: config.showHeader, //是否显示表头 |
|||
showOverflow: true, //设置所有内容过长时显示为省略号 |
|||
headerRowClassName: "headerRowClass", //表头的行附加 className |
|||
headerCellClassName: "headerCellClass", //头的单元格附加 className |
|||
rowClassName: "rowClass", //行附加 className |
|||
cellClassName: "cellClass", //单元格附加 className |
|||
keepSource: true, //保持原始值的状态,被某些功能所依赖,比如编辑状态、还原数据等 |
|||
columnConfig: { |
|||
//列配置信息 |
|||
isCurrent: config.columnConfig.isCurrent, //当鼠标点击列头时,是否要高亮当前列 |
|||
isHover: config.columnConfig.isHover, //当鼠标移到列头时,是否要高亮当前头 |
|||
resizable: true, //每一列是否启用列宽调整 |
|||
}, |
|||
rowConfig: { |
|||
//行配置信息 |
|||
keyField: config.rowConfig.keyField, //自定义行数据唯一主键的字段名 |
|||
isCurrent: config.rowConfig.isCurrent, //当鼠标点击行时,是否要高亮当前行 |
|||
isHover: config.rowConfig.isHover, //当鼠标移到行时,是否要高亮当前行 |
|||
}, |
|||
sortConfig: { |
|||
//排序配置项 |
|||
trigger: "cell", //触发方式 |
|||
multiple: false, //是否启用多列组合筛选 |
|||
remote: false, //所有列是否使用服务端排序,如果设置为 true 则不会对数据进行处理 |
|||
}, |
|||
filterConfig: { |
|||
//筛选配置项 |
|||
remote: true, //所有列是否使用服务端筛选,如果设置为 true 则不会对数据进行处理 |
|||
}, |
|||
editConfig: { |
|||
//可编辑配置项 |
|||
trigger: config.editConfig.trigger, //触发方式click(点击触发编辑),dblclick(双击触发编辑) |
|||
mode: config.editConfig.mode, //编辑模式cell(单元格编辑模式),row(行编辑模式) |
|||
showStatus: true, //只对 keep-source 开启有效,是否显示单元格新增与修改状态 |
|||
beforeEditMethod(param) { |
|||
let shouldContinue; |
|||
emit("beforeEditRowsCallBack", param); |
|||
emit("validateFormMethod", param, val => { |
|||
shouldContinue = val |
|||
}); |
|||
if (shouldContinue || shouldContinue === undefined) { |
|||
return true; |
|||
} else { |
|||
return false; |
|||
} |
|||
} |
|||
}, |
|||
pagerConfig: { |
|||
//分页配置项 |
|||
enabled: config.pagerConfig.enabled, //是否启用 |
|||
currentPage: config.pagerConfig.currentPage, //当前页 |
|||
pageSize: config.pagerConfig.pageSize, //每页大小 |
|||
total: config.pagerConfig.total, //总条数 |
|||
autoHidden: config.pagerConfig.autoHidden, //当只有一页时自动隐藏 |
|||
pageSizes: config.pagerConfig.pageSizes, //每页大小选项列表 |
|||
}, |
|||
toolbarConfig: { |
|||
//工具栏配置 |
|||
slots: { |
|||
//插槽 |
|||
buttons: "toolbar_buttons", |
|||
}, |
|||
refresh: config.toolbarConfig.refresh, // 显示刷新按钮 |
|||
import: config.toolbarConfig.import, // 显示导入按钮 |
|||
export: config.toolbarConfig.export, // 显示导出按钮 |
|||
// print: true, // 显示打印按钮 |
|||
zoom: config.toolbarConfig.zoom, // 显示全屏按钮 |
|||
custom: config.toolbarConfig.custom, // 显示自定义列按钮 |
|||
}, |
|||
importConfig: { |
|||
//导入配置项 |
|||
remote: false, //是否服务端导入 |
|||
types: ["csv", "html", "xml", "txt"], |
|||
modes: ["covering", "insert"], |
|||
}, |
|||
exportConfig: { |
|||
//导出配置项 |
|||
remote: false, //是否服务端导出 |
|||
types: ["csv", "html", "xml", "txt"], //可选文件类型列表 |
|||
modes: ["current", "selected", "all"], //输出数据的方式列表 |
|||
}, |
|||
editRules: config.editRules, //校验规则配置项 |
|||
// columns: config.columns, |
|||
// data: config.data, |
|||
}); |
|||
|
|||
const addRow = async (row) => { |
|||
const $table = tableRef.value; |
|||
//新增按钮 |
|||
if (addRowsType === 1) { |
|||
//新增功能 |
|||
if ($table) { |
|||
let shouldContinue = true; |
|||
emit("beforeAddRowsCallBack", $table, val => { shouldContinue = val }); |
|||
if (shouldContinue || shouldContinue === undefined) { |
|||
const record = props.additional; |
|||
const { row: newRow } = await $table.insertAt(record, row); |
|||
await $table.setEditCell(newRow, colField); |
|||
emit("addRowsCallBack", newRow); |
|||
calculateTableHeight(null); |
|||
} else { |
|||
// 不继续执行下面的代码 |
|||
return; |
|||
} |
|||
|
|||
} |
|||
} else if (addRowsType === 2) { |
|||
//新增功能 |
|||
if ($table) { |
|||
let shouldContinue = true; |
|||
|
|||
console.log("shouldContinue"); |
|||
emit("beforeAddRowsCallBack", $table, val => { shouldContinue = val }); |
|||
if (shouldContinue || shouldContinue === undefined) {debugger |
|||
//纯按钮功能 |
|||
emit("btnClick", "") |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
const delSelect = async () => { |
|||
//多选删除 |
|||
const $table = tableRef.value; |
|||
const selectRecords = $table.getCheckboxRecords(); |
|||
if ($table && selectRecords.length != 0) { |
|||
const type = await VXETable.modal.confirm("您确定要删除该数据?"); |
|||
if (type === "confirm") { |
|||
emit("delSelectData", selectRecords); |
|||
$table.removeCheckboxRow(); |
|||
} |
|||
} else { |
|||
VXETable.modal.message({ |
|||
content: "请选择要删除的数据!", |
|||
status: "warning", |
|||
}); |
|||
} |
|||
}; |
|||
const allSave = async () => { |
|||
//多行编辑保存 |
|||
const $table = tableRef.value; |
|||
if ($table) { |
|||
const $grid = tableRef.value; |
|||
const errMap = await $grid.validate(true); |
|||
if (errMap) { |
|||
VXETable.modal.message({ status: "error", content: "请填写相关内容!" }); |
|||
} else { |
|||
// const updateRecords = $table.getUpdateRecords(); |
|||
const { insertRecords, removeRecords, updateRecords } = |
|||
$grid.getRecordset(); |
|||
if (insertRecords.length != 0) { |
|||
console.log(insertRecords); |
|||
//新增 |
|||
emit("insertRecords", insertRecords); |
|||
} else if (updateRecords.length != 0) { |
|||
//修改 |
|||
emit("updateRecords", updateRecords); |
|||
} |
|||
|
|||
} |
|||
} |
|||
}; |
|||
const hasEditRows = (row) => { |
|||
//显示编辑或保存按钮 |
|||
const $grid = tableRef.value; |
|||
if ($grid) { |
|||
return $grid.isEditByRow(row); |
|||
} |
|||
return false; |
|||
}; |
|||
const editRowClick = async (row) => { |
|||
//点击编辑 |
|||
const $grid = tableRef.value; |
|||
if ($grid) { |
|||
const payload = { |
|||
grid: $grid, |
|||
row: row |
|||
}; |
|||
$grid.setEditRow(row); |
|||
} |
|||
}; |
|||
const cancelRowClick = () => { |
|||
//点击取消 |
|||
const $grid = tableRef.value; |
|||
if ($grid) { |
|||
$grid.clearEdit(); |
|||
} |
|||
}; |
|||
const saveRowClick = async (row) => { |
|||
//编辑保存 |
|||
const $grid = tableRef.value; |
|||
if ($grid) { |
|||
const errMap = await $grid.validate(true); |
|||
if (errMap) { |
|||
VXETable.modal.message({ status: "error", content: "请填写相关内容!" }); |
|||
} else { |
|||
await $grid.clearEdit(); |
|||
const { insertRecords, removeRecords, updateRecords } = |
|||
$grid.getRecordset(); |
|||
if (insertRecords.length != 0) { |
|||
//新增 |
|||
emit("insertRecords", insertRecords) |
|||
} else if (updateRecords.length != 0) { |
|||
//修改 |
|||
emit("updateRecords", updateRecords) |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
const saveRowClickNew = async (row) => { |
|||
//编辑保存 |
|||
const $grid = tableRef.value; |
|||
if ($grid) { |
|||
const errMap = await $grid.validate(true); |
|||
if (errMap) { |
|||
VXETable.modal.message({ status: "error", content: "请填写相关内容!" }); |
|||
} else { |
|||
await $grid.clearEdit(); |
|||
} |
|||
} |
|||
}; |
|||
const delRowClick = async (row) => { |
|||
//单行删除 |
|||
const type = await VXETable.modal.confirm("您确定要删除该数据?"); |
|||
const $grid = tableRef.value; |
|||
if ($grid) { |
|||
if (type === "confirm") { |
|||
emit("delRowData", row); |
|||
await $grid.remove(row); |
|||
} |
|||
} |
|||
}; |
|||
const cellDBLClickEvent = ({ row, column, $event }) => { |
|||
//双击单元格事件 |
|||
emit("cellDBLClick", row, column, $event); |
|||
}; |
|||
const pageChange = ({ currentPage, pageSize }) => { |
|||
//分页 |
|||
emit("pageChange", currentPage, pageSize); |
|||
}; |
|||
|
|||
// 动态计算函数 |
|||
function calculateTableHeight(rowHeightNew) { |
|||
const $table = tableRef.value |
|||
let newRowNum = 0; |
|||
let pageHeight = 0; |
|||
if (rowHeightNew) { |
|||
rowHeight.value = rowHeightNew; |
|||
} |
|||
if ($table) { |
|||
const insertRecords = $table.getInsertRecords() |
|||
newRowNum = insertRecords.length; |
|||
} |
|||
if (props.pagination.total > 10) { |
|||
pageHeight = 44; |
|||
} |
|||
const rowCount = props.tableData?.length |
|||
headerHeight.value = tableRef.value.$el.querySelector('.vxe-header--row')?.offsetHeight |
|||
tableHeight.value = (newRowNum + rowCount) * (rowHeight.value + 1.8) + (48.8 + pageHeight + 5) + headerHeight.value + 'px' |
|||
} |
|||
|
|||
//监控config的变化,目前重新计算了表格高度 |
|||
watch(config, (newConfig) => { |
|||
console.log('newConfig'); |
|||
console.log(newConfig); |
|||
// 监听 config 变化的处理逻辑 |
|||
gridOptions.minHeight = newConfig.minHeight; |
|||
gridOptions.maxHeight = newConfig.maxHeight; |
|||
rowHeight.value = newConfig.rowHeight; |
|||
gridOptions.pagerConfig.currentPage = newConfig.pagerConfig.currentPage; |
|||
gridOptions.pagerConfig.pageSize = newConfig.pagerConfig.pageSize; |
|||
gridOptions.pagerConfig.total = newConfig.pagerConfig.total; |
|||
|
|||
}, { deep: true }); |
|||
|
|||
//自定义表格高度根据行数行高自动调节,监控props.tableData的变化 |
|||
watch(() => props.tableData, (newTableData) => { |
|||
calculateTableHeight(config.rowHeight); |
|||
}, { deep: true }); |
|||
|
|||
//动态行样式 |
|||
//1、获取响应式变量高度,其中rowHeight=ref(config.rowHeight); |
|||
function getRowStyle() { |
|||
return { height: rowHeight.value + 'px' }; |
|||
} |
|||
|
|||
function onEditActivated(params) { |
|||
const { row, $table } = params; |
|||
// 遍历每一列 |
|||
$table.getColumns().forEach(column => { |
|||
// 判断是否包含某属性 |
|||
if (column && column?.slots!==undefined) { |
|||
if(column.slots.hasOwnProperty('editActiveMethod')){ |
|||
//当包含编辑激活回调函数时则调用该函数 |
|||
column.slots.editActiveMethod(row,column); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function getButtonInfo($table, row, operate, buttonDom) { |
|||
const columns = $table.getColumns(); |
|||
for (let i = 0; i < columns.length; i++) { |
|||
let column = columns[i]; |
|||
if(column?.title !== '操作'){ |
|||
continue; |
|||
} |
|||
if (column && column?.slots!==undefined) { |
|||
if(column.slots.hasOwnProperty(buttonDom)){ |
|||
if (column.slots[buttonDom]) { |
|||
const template = column.slots[buttonDom]; |
|||
if(operate === 'name'){ |
|||
if(template.hasOwnProperty('name')){ |
|||
return template.name; |
|||
} |
|||
}else if(operate === 'btn'){ |
|||
if(template.hasOwnProperty('click')){ |
|||
return template.click(row); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return ''; |
|||
} |
|||
|
|||
function getButtonShow($table, row, buttonDom) { |
|||
const columns = $table.getColumns(); |
|||
for (let i = 0; i < columns.length; i++) { |
|||
let column = columns[i]; |
|||
if(column?.title !== '操作'){ |
|||
continue; |
|||
} |
|||
if (column && column?.slots!==undefined) { |
|||
if(column.slots.hasOwnProperty(buttonDom)){ |
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
async function addRows(num) { |
|||
const $table = tableRef.value; |
|||
const record = props.additional; |
|||
let records = new Array(num).fill(record); |
|||
emit("addRowsCallBack",records, results => records = results); |
|||
await $table.insertAt(records, null); |
|||
calculateTableHeight(); |
|||
} |
|||
|
|||
|
|||
//自定义表格高度根据行数行高自动调节 |
|||
// watch(() => tableRef?.value?.getInsertRecords(), (newTableData) => { |
|||
// calculateTableHeight(); |
|||
// }, { deep: true }); |
|||
|
|||
function getInsertRows() { |
|||
const $table = tableRef.value; |
|||
return $table.getInsertRecords(); |
|||
} |
|||
|
|||
const allSubmit = async (callback) => { |
|||
//多行编辑保存 |
|||
const $table = tableRef.value; |
|||
if ($table) { |
|||
const $grid = tableRef.value; |
|||
const errMap = await $grid.validate(true); |
|||
if (errMap) { |
|||
VXETable.modal.message({ status: "error", content: "请填写相关内容!" }); |
|||
} else { |
|||
// const updateRecords = $table.getUpdateRecords(); |
|||
const { insertRecords, removeRecords, updateRecords } = |
|||
$grid.getRecordset(); |
|||
if (insertRecords.length != 0) { |
|||
console.log(insertRecords); |
|||
//新增 |
|||
emit("insertRecords", insertRecords); |
|||
} else if (updateRecords.length != 0) { |
|||
//修改 |
|||
emit("updateRecords", updateRecords); |
|||
} |
|||
await callback(); |
|||
} |
|||
|
|||
} |
|||
}; |
|||
|
|||
// // 将方法暴露出去 |
|||
defineExpose({ addRows,getInsertRows,allSave,allSubmit }); |
|||
|
|||
</script> |
|||
|
|||
<style lang="scss"></style> |
@ -0,0 +1,37 @@ |
|||
import VXETable from 'vxe-table' |
|||
import 'vxe-table/lib/style.css' |
|||
|
|||
// 自行按照,具体 echarts 看文档
|
|||
import 'echarts/lib/chart/bar' |
|||
import 'echarts/lib/chart/pie' |
|||
import 'echarts/lib/chart/line' |
|||
import 'echarts/lib/component/grid' |
|||
import 'echarts/lib/component/tooltip' |
|||
import 'echarts/lib/component/legend' |
|||
import 'echarts/lib/component/legendScroll' |
|||
|
|||
// 引入 vxe-table pro
|
|||
import './pro/vxe-table-pro.es6.min' |
|||
import './pro/vxe-table-pro.min.css' |
|||
|
|||
// 引入快捷菜单插件(可选)
|
|||
import VXETablePluginMenus from 'vxe-table-plugin-menus' |
|||
// 引入图表插件(可选)
|
|||
import VXETablePluginCharts from 'vxe-table-plugin-charts' |
|||
import 'vxe-table-plugin-charts/dist/style.css' |
|||
|
|||
// 全局默认参数
|
|||
VXETable.config({ |
|||
authId: '1kedlpuyjow1v7ez', // Auth ID 在官网登录查看(必须,重要!!!)
|
|||
version: 4, // 版本号,对于某些带数据缓存的功能有用到,上升版本号可以用于重置数据
|
|||
zIndex: 999 // 全局 zIndex 起始值,如果项目的的 z-index 样式值过大时就需要跟随设置更大,避免被遮挡
|
|||
}) |
|||
|
|||
// 安装快捷菜单插件(可选)
|
|||
VXETable.use(VXETablePluginMenus) |
|||
// 安装图表插件(可选)
|
|||
VXETable.use(VXETablePluginCharts) |
|||
|
|||
export function useTable (app) { |
|||
app.use(VXETable) |
|||
} |
@ -0,0 +1,170 @@ |
|||
.vxe-table--fnr.vxe-modal--wrapper .vxe-modal--content { |
|||
padding: 0; |
|||
} |
|||
.vxe-table--fnr.vxe-modal--wrapper .vxe-modal--content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.vxe-table--fnr .vxe-table--fnr-tabs { |
|||
flex-shrink: 0; |
|||
border-bottom: 1px solid #e8eaec; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
user-select: none; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-tabs > span { |
|||
position: relative; |
|||
display: inline-block; |
|||
padding: 0 1em; |
|||
height: 2.4em; |
|||
line-height: 2.4em; |
|||
text-align: center; |
|||
border-right: 1px solid #e8eaec; |
|||
background-color: #F8F8F9; |
|||
vertical-align: bottom; |
|||
cursor: pointer; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-tabs > span.is--active { |
|||
background-color: #fff; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-tabs > span.is--active:after { |
|||
content: ""; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: -1px; |
|||
width: 100%; |
|||
height: 1px; |
|||
background-color: #fff; |
|||
z-index: 1; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-tabs > span:not(.is--active) { |
|||
color: #909399; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-body { |
|||
flex-shrink: 0; |
|||
padding: 0.3em 1em 0 1em; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-form { |
|||
width: 100%; |
|||
border: 0; |
|||
border-spacing: 0; |
|||
border-collapse: separate; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-form tr { |
|||
visibility: hidden; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-form tr.is--visible { |
|||
visibility: visible; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-form-title { |
|||
white-space: nowrap; |
|||
padding-right: 0.8em; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-form-content, |
|||
.vxe-table--fnr .vxe-table--fnr-form-input { |
|||
width: 100%; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-form-content { |
|||
padding: 0.3em 0; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-form-filter { |
|||
padding-left: 1.8em; |
|||
vertical-align: top; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-form-filter > .vxe-checkbox { |
|||
display: block; |
|||
margin: 0.6em 0 0 0; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-footer { |
|||
flex-shrink: 0; |
|||
padding: 0.8em 1em; |
|||
overflow: hidden; |
|||
text-align: right; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search { |
|||
display: flex; |
|||
flex-direction: column; |
|||
flex-grow: 1; |
|||
border-top: 1px solid #e8eaec; |
|||
border-bottom: 1px solid #e8eaec; |
|||
overflow: hidden; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search .vxe-table--fnr-search-list, |
|||
.vxe-table--fnr .vxe-table--fnr-search .vxe-list--virtual-wrapper { |
|||
height: 100%; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-header { |
|||
flex-shrink: 0; |
|||
height: 2.5em; |
|||
line-height: 2.5em; |
|||
padding: 0 0.8em; |
|||
font-weight: 700; |
|||
background-color: #f8f8f8; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-header, |
|||
.vxe-table--fnr .vxe-table--fnr-find-item { |
|||
display: flex; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-header > div, |
|||
.vxe-table--fnr .vxe-table--fnr-find-item > div { |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
user-select: none; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-header > div:nth-child(1), |
|||
.vxe-table--fnr .vxe-table--fnr-find-item > div:nth-child(1) { |
|||
width: 100px; |
|||
flex-shrink: 0; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-header > div:nth-child(2), |
|||
.vxe-table--fnr .vxe-table--fnr-find-item > div:nth-child(2) { |
|||
width: 160px; |
|||
flex-shrink: 0; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-header > div:nth-child(3), |
|||
.vxe-table--fnr .vxe-table--fnr-find-item > div:nth-child(3) { |
|||
flex-grow: 1; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-body { |
|||
flex-grow: 1; |
|||
overflow: hidden; |
|||
border-top: 1px solid #e8eaec; |
|||
border-bottom: 1px solid #e8eaec; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-find-item { |
|||
height: 2em; |
|||
line-height: 2em; |
|||
padding: 0 0.8em; |
|||
cursor: pointer; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-find-item.is--active { |
|||
font-weight: 700; |
|||
color: #409eff; |
|||
background-color: #e6f7ff; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-find-item:hover { |
|||
color: #409eff; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-find-item:hover.is--active { |
|||
background-color: #d7effb; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-find-item:hover > div { |
|||
text-decoration: underline; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-footer { |
|||
flex-shrink: 0; |
|||
height: 2em; |
|||
line-height: 2em; |
|||
padding: 0 0.8em; |
|||
visibility: hidden; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-footer.is--error { |
|||
color: #f56c6c; |
|||
} |
|||
.vxe-table--fnr .vxe-table--fnr-search-footer.is--visible { |
|||
visibility: visible; |
|||
} |
@ -0,0 +1,7 @@ |
|||
/** |
|||
* vxe-table pro v2.1.6 |
|||
* Purchase authorization: https://vxetable.cn/plugins/
|
|||
* @copyright x_extends@163.com |
|||
*/ |
|||
export const VXETablePro: {} |
|||
export default VXETablePro |
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@ |
|||
.vxe-table--fnr.vxe-modal--wrapper .vxe-modal--content{padding:0}.vxe-table--fnr.vxe-modal--wrapper .vxe-modal--content{display:flex;flex-direction:column}.vxe-table--fnr .vxe-table--fnr-tabs{flex-shrink:0;border-bottom:1px solid #e8eaec;-webkit-user-select:none;-moz-user-select:none;user-select:none}.vxe-table--fnr .vxe-table--fnr-tabs>span{position:relative;display:inline-block;padding:0 1em;height:2.4em;line-height:2.4em;text-align:center;border-right:1px solid #e8eaec;background-color:#f8f8f9;vertical-align:bottom;cursor:pointer}.vxe-table--fnr .vxe-table--fnr-tabs>span.is--active{background-color:#fff}.vxe-table--fnr .vxe-table--fnr-tabs>span.is--active:after{content:"";position:absolute;left:0;bottom:-1px;width:100%;height:1px;background-color:#fff;z-index:1}.vxe-table--fnr .vxe-table--fnr-tabs>span:not(.is--active){color:#909399}.vxe-table--fnr .vxe-table--fnr-body{flex-shrink:0;padding:.3em 1em 0 1em}.vxe-table--fnr .vxe-table--fnr-form{width:100%;border:0;border-spacing:0;border-collapse:separate}.vxe-table--fnr .vxe-table--fnr-form tr{visibility:hidden}.vxe-table--fnr .vxe-table--fnr-form tr.is--visible{visibility:visible}.vxe-table--fnr .vxe-table--fnr-form-title{white-space:nowrap;padding-right:.8em}.vxe-table--fnr .vxe-table--fnr-form-content,.vxe-table--fnr .vxe-table--fnr-form-input{width:100%}.vxe-table--fnr .vxe-table--fnr-form-content{padding:.3em 0}.vxe-table--fnr .vxe-table--fnr-form-filter{padding-left:1.8em;vertical-align:top}.vxe-table--fnr .vxe-table--fnr-form-filter>.vxe-checkbox{display:block;margin:.6em 0 0 0}.vxe-table--fnr .vxe-table--fnr-footer{flex-shrink:0;padding:.8em 1em;overflow:hidden;text-align:right}.vxe-table--fnr .vxe-table--fnr-search{display:flex;flex-direction:column;flex-grow:1;border-top:1px solid #e8eaec;border-bottom:1px solid #e8eaec;overflow:hidden}.vxe-table--fnr .vxe-table--fnr-search .vxe-list--virtual-wrapper,.vxe-table--fnr .vxe-table--fnr-search .vxe-table--fnr-search-list{height:100%}.vxe-table--fnr .vxe-table--fnr-search-header{flex-shrink:0;height:2.5em;line-height:2.5em;padding:0 .8em;font-weight:700;background-color:#f8f8f8}.vxe-table--fnr .vxe-table--fnr-find-item,.vxe-table--fnr .vxe-table--fnr-search-header{display:flex}.vxe-table--fnr .vxe-table--fnr-find-item>div,.vxe-table--fnr .vxe-table--fnr-search-header>div{-webkit-user-select:none;-moz-user-select:none;user-select:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vxe-table--fnr .vxe-table--fnr-find-item>div:nth-child(1),.vxe-table--fnr .vxe-table--fnr-search-header>div:nth-child(1){width:100px;flex-shrink:0}.vxe-table--fnr .vxe-table--fnr-find-item>div:nth-child(2),.vxe-table--fnr .vxe-table--fnr-search-header>div:nth-child(2){width:160px;flex-shrink:0}.vxe-table--fnr .vxe-table--fnr-find-item>div:nth-child(3),.vxe-table--fnr .vxe-table--fnr-search-header>div:nth-child(3){flex-grow:1}.vxe-table--fnr .vxe-table--fnr-search-body{flex-grow:1;overflow:hidden;border-top:1px solid #e8eaec;border-bottom:1px solid #e8eaec}.vxe-table--fnr .vxe-table--fnr-find-item{height:2em;line-height:2em;padding:0 .8em;cursor:pointer}.vxe-table--fnr .vxe-table--fnr-find-item.is--active{font-weight:700;color:#409eff;background-color:#e6f7ff}.vxe-table--fnr .vxe-table--fnr-find-item:hover{color:#409eff}.vxe-table--fnr .vxe-table--fnr-find-item:hover.is--active{background-color:#d7effb}.vxe-table--fnr .vxe-table--fnr-find-item:hover>div{text-decoration:underline}.vxe-table--fnr .vxe-table--fnr-search-footer{flex-shrink:0;height:2em;line-height:2em;padding:0 .8em;visibility:hidden}.vxe-table--fnr .vxe-table--fnr-search-footer.is--error{color:#f56c6c}.vxe-table--fnr .vxe-table--fnr-search-footer.is--visible{visibility:visible} |
@ -0,0 +1,168 @@ |
|||
.vxe-table--fnr { |
|||
&.vxe-modal--wrapper { |
|||
.vxe-modal--content { |
|||
padding: 0; |
|||
} |
|||
.vxe-modal--content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.vxe-table--fnr { |
|||
.vxe-table--fnr-tabs { |
|||
flex-shrink: 0; |
|||
border-bottom: 1px solid #e8eaec; |
|||
user-select: none; |
|||
& > span { |
|||
position: relative; |
|||
display: inline-block; |
|||
padding: 0 1em; |
|||
height: 2.4em; |
|||
line-height: 2.4em; |
|||
text-align: center; |
|||
border-right: 1px solid #e8eaec; |
|||
background-color: #F8F8F9; |
|||
vertical-align: bottom; |
|||
cursor: pointer; |
|||
&.is--active { |
|||
background-color: #fff; |
|||
&:after { |
|||
content: ""; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: -1px; |
|||
width: 100%; |
|||
height: 1px; |
|||
background-color: #fff; |
|||
z-index: 1; |
|||
} |
|||
} |
|||
&:not(.is--active) { |
|||
color: #909399; |
|||
} |
|||
} |
|||
} |
|||
.vxe-table--fnr-body { |
|||
flex-shrink: 0; |
|||
padding: 0.3em 1em 0 1em; |
|||
} |
|||
.vxe-table--fnr-form { |
|||
width: 100%; |
|||
border: 0; |
|||
border-spacing: 0; |
|||
border-collapse: separate; |
|||
tr { |
|||
visibility: hidden; |
|||
&.is--visible { |
|||
visibility: visible; |
|||
} |
|||
} |
|||
} |
|||
.vxe-table--fnr-form-title { |
|||
white-space: nowrap; |
|||
padding-right: 0.8em; |
|||
} |
|||
.vxe-table--fnr-form-content, |
|||
.vxe-table--fnr-form-input { |
|||
width: 100%; |
|||
} |
|||
.vxe-table--fnr-form-content { |
|||
padding: 0.3em 0; |
|||
} |
|||
.vxe-table--fnr-form-filter { |
|||
padding-left: 1.8em; |
|||
vertical-align: top; |
|||
& > .vxe-checkbox { |
|||
display: block; |
|||
margin: 0.6em 0 0 0; |
|||
} |
|||
} |
|||
.vxe-table--fnr-footer { |
|||
flex-shrink: 0; |
|||
padding: 0.8em 1em; |
|||
overflow: hidden; |
|||
text-align: right; |
|||
} |
|||
.vxe-table--fnr-search { |
|||
display: flex; |
|||
flex-direction: column; |
|||
flex-grow: 1; |
|||
border-top: 1px solid #e8eaec; |
|||
border-bottom: 1px solid #e8eaec; |
|||
overflow: hidden; |
|||
.vxe-table--fnr-search-list, |
|||
.vxe-list--virtual-wrapper { |
|||
height: 100%; |
|||
} |
|||
} |
|||
.vxe-table--fnr-search-header { |
|||
flex-shrink: 0; |
|||
height: 2.5em; |
|||
line-height: 2.5em; |
|||
padding: 0 0.8em; |
|||
font-weight: 700; |
|||
background-color: #f8f8f8; |
|||
} |
|||
.vxe-table--fnr-search-header, |
|||
.vxe-table--fnr-find-item { |
|||
display: flex; |
|||
& > div { |
|||
user-select: none; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
&:nth-child(1) { |
|||
width: 100px; |
|||
flex-shrink: 0; |
|||
} |
|||
&:nth-child(2) { |
|||
width: 160px; |
|||
flex-shrink: 0; |
|||
} |
|||
&:nth-child(3) { |
|||
flex-grow: 1; |
|||
} |
|||
} |
|||
} |
|||
.vxe-table--fnr-search-body { |
|||
flex-grow: 1; |
|||
overflow: hidden; |
|||
border-top: 1px solid #e8eaec; |
|||
border-bottom: 1px solid #e8eaec; |
|||
} |
|||
.vxe-table--fnr-find-item { |
|||
height: 2em; |
|||
line-height: 2em; |
|||
padding: 0 0.8em; |
|||
cursor: pointer; |
|||
&.is--active { |
|||
font-weight: 700; |
|||
color: #409eff; |
|||
background-color: #e6f7ff; |
|||
} |
|||
&:hover { |
|||
color: #409eff; |
|||
&.is--active { |
|||
background-color: #d7effb; |
|||
} |
|||
& > div { |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
} |
|||
.vxe-table--fnr-search-footer { |
|||
flex-shrink: 0; |
|||
height: 2em; |
|||
line-height: 2em; |
|||
padding: 0 0.8em; |
|||
visibility: hidden; |
|||
&.is--error { |
|||
color: #f56c6c; |
|||
} |
|||
&.is--visible { |
|||
visibility: visible; |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue