import { h, useSlots } from "vue"; import { useBrowser, useConfig, useCore } from "../../../hooks"; import { assign, cloneDeep, isArray, isEmpty, isObject, isString, orderBy } from "lodash-es"; import { deepFind, getValue } from "../../../utils"; 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 = ( ); // 操作按钮 if (item.type === "op") { const props = assign( { label: crud.dict.label.op, width: style.table.column.opWidth, fixed: browser.isMini ? null : "right" }, item ); return h(ElTableColumn, props, { default: (scope: any) => { return (
{renderOpButtons(item.buttons, { scope })}
); } }); } // 多选,序号 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 # 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 (isObject(value)) { return value; } } // 自定义渲染 if (item.render) { return item.render( scope.row, scope.column, value, scope.$index ); } // 自定义渲染2 else 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 renderDict(value, item); } // 空数据 else if (isEmpty(value)) { return scope.emptyText; } else { return value; } } } }); } return deep(item); } }) .filter(Boolean); } // 渲染操作按钮 function renderOpButtons(buttons: any, { scope }: any) { const list = getValue(buttons || ["edit", "delete"], { scope }) as ClTable.OpButton; return list.map((vnode) => { if (vnode === "info") { return ( { crud.rowInfo(scope.row); e.stopPropagation(); }}> {crud.dict.label?.info} ); } else if (vnode === "edit") { return ( { crud.rowEdit(scope.row); e.stopPropagation(); }}> {crud.dict.label?.update} ); } else if (vnode === "delete") { return ( { crud.rowDelete(scope.row); e.stopPropagation(); }}> {crud.dict.label?.delete} ); } else { if (typeof vnode === "object") { if (vnode.hidden) { return null; } } return renderNode(vnode, { scope, slots, custom(vnode) { return ( { vnode.onClick({ scope }); e.stopPropagation(); }}> {vnode.label} ); } }); } }); } // 渲染字典 function renderDict(value: any, item: ClTable.Column) { // 选项列表 const list = cloneDeep(item.dict || []) as DictOptions; // 字符串分隔符 const separator = item.dictSeparator === undefined ? "," : item.dictSeparator; // 设置颜色 if (item.dictColor) { list.forEach((e, i) => { if (!e.color) { e.color = style.colors[i]; } }); } // 绑定值 let values: any[] = []; // 格式化值 if (isArray(value)) { values = value; } else if (isString(value)) { if (separator) { values = value.split(separator); } else { values = [value]; } } else { values = [value]; } // 返回值 const result = values .filter((e) => e !== undefined && e !== null && e !== "") .map((v) => { const d = deepFind(v, list, { allLevels: item.dictAllLevels }) || { label: v, value: v }; return { ...d, children: [] }; }); // 格式化返回 if (item.dictFormatter) { return item.dictFormatter(result); } else { // tag 返回 return result.map((e) => { return h( , { type: e.type, closable: e.closable, hit: e.hit, color: e.color, size: e.size, effect: e.effect || "dark", round: e.round }, { default: () => {e.label} } ); }); } } // 插槽 empty function renderEmpty(emptyText: string) { return (
{slots.empty ? ( slots.empty() ) : ( )}
); } // 插槽 append function renderAppend() { return
{slots.append && slots.append()}
; } return { renderColumn, renderEmpty, renderAppend }; }