mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2025-12-14 06:42:51 +00:00
168 lines
3.6 KiB
TypeScript
168 lines
3.6 KiB
TypeScript
import { h, useSlots } from "vue";
|
|
import { useCore, useBrowser, useConfig } from "../../../hooks";
|
|
import { cloneDeep, isEmpty, orderBy } from "lodash-es";
|
|
import { getValue } from "../../../utils";
|
|
import { parseTableDict, parseTableOpButtons } from "../../../utils/parse";
|
|
import { renderNode } from "../../../utils/vnode";
|
|
import { renderHeader } from "./header";
|
|
|
|
// 渲染
|
|
export function useRender() {
|
|
const browser = useBrowser();
|
|
const slots = useSlots();
|
|
const { crud } = useCore();
|
|
const { style } = useConfig();
|
|
|
|
// 渲染列
|
|
function renderColumn(columns: ClTable.Column[]) {
|
|
const arr = columns.map((e) => {
|
|
const d = getValue(e);
|
|
|
|
if (!d.orderNum) {
|
|
d.orderNum = 0;
|
|
}
|
|
|
|
return d;
|
|
});
|
|
|
|
return orderBy(arr, "orderNum", "asc")
|
|
.map((item, index) => {
|
|
if (item.hidden) {
|
|
return null;
|
|
}
|
|
|
|
const ElTableColumn = (
|
|
<el-table-column
|
|
key={`cl-table-column__${index}`}
|
|
align={style.table.column.align}
|
|
header-align={style.table.column.headerAlign}
|
|
minWidth={style.table.column.minWidth}
|
|
/>
|
|
);
|
|
|
|
// 操作按钮
|
|
if (item.type === "op") {
|
|
return h(
|
|
ElTableColumn,
|
|
{
|
|
label: crud.dict.label.op,
|
|
width: style.table.column.opWidth,
|
|
fixed: browser.isMini ? null : "right",
|
|
...item
|
|
},
|
|
{
|
|
default: (scope: any) => {
|
|
return (
|
|
<div class="cl-table__op">
|
|
{parseTableOpButtons(item.buttons, { scope })}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
// 多选,序号
|
|
else if (["selection", "index"].includes(item.type)) {
|
|
return h(ElTableColumn, item);
|
|
}
|
|
// 默认
|
|
else {
|
|
function deep(item: ClTable.Column) {
|
|
if (item.hidden) {
|
|
return null;
|
|
}
|
|
|
|
const props: obj = cloneDeep(item);
|
|
|
|
// Cannot set property children of #<Element>
|
|
delete props.children;
|
|
|
|
return h(ElTableColumn, props, {
|
|
header(scope: any) {
|
|
return renderHeader(item, { scope, slots });
|
|
},
|
|
default(scope: any) {
|
|
if (item.children) {
|
|
return item.children.map(deep);
|
|
}
|
|
|
|
// 使用插槽
|
|
const slot = slots[`column-${item.prop}`];
|
|
|
|
if (slot) {
|
|
return slot({
|
|
scope,
|
|
item
|
|
});
|
|
} else {
|
|
// 绑定值
|
|
let value = scope.row[item.prop];
|
|
|
|
// 格式化
|
|
if (item.formatter) {
|
|
value = item.formatter(
|
|
scope.row,
|
|
scope.column,
|
|
value,
|
|
scope.$index
|
|
);
|
|
}
|
|
|
|
// 自定义渲染
|
|
if (item.component) {
|
|
return renderNode(item.component, {
|
|
prop: item.prop,
|
|
scope: scope.row,
|
|
_data: {
|
|
column: scope.column,
|
|
index: scope.$index,
|
|
row: scope.row
|
|
}
|
|
});
|
|
}
|
|
// 字典状态
|
|
else if (item.dict) {
|
|
return parseTableDict(value, item);
|
|
}
|
|
// 空数据
|
|
else if (isEmpty(value)) {
|
|
return scope.emptyText;
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
return deep(item);
|
|
}
|
|
})
|
|
.filter(Boolean);
|
|
}
|
|
|
|
// 插槽 empty
|
|
function renderEmpty(emptyText: String) {
|
|
return (
|
|
<div class="cl-table__empty">
|
|
{slots.empty ? (
|
|
slots.empty()
|
|
) : (
|
|
<el-empty image-size={100} description={emptyText}></el-empty>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// 插槽 append
|
|
function renderAppend() {
|
|
return <div class="cl-table__append">{slots.append && slots.append()}</div>;
|
|
}
|
|
|
|
return {
|
|
renderColumn,
|
|
renderEmpty,
|
|
renderAppend
|
|
};
|
|
}
|