vue3-smart-table 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/vue3-smart-table.cjs.js +1 -1
- package/dist/vue3-smart-table.cjs.js.map +1 -1
- package/dist/vue3-smart-table.es.js +101 -93
- package/dist/vue3-smart-table.es.js.map +1 -1
- package/dist/vue3-smart-table.umd.js +2 -2
- package/dist/vue3-smart-table.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/SmartTable/renderers/index.ts +11 -2
- package/src/components/SmartTable/types.ts +3 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue3-smart-table.es.js","sources":["../src/components/SmartTable/renderer.ts","../src/components/SmartTable/utils/path.ts","../src/components/SmartTable/renderers/input.vue","../src/components/SmartTable/renderers/inputNumber.vue","../src/components/SmartTable/renderers/select.vue","../src/components/SmartTable/renderers/index.ts","../src/components/SmartTable/hooks/useOperationColumn.ts","../src/components/SmartTable/column/index.vue","../src/components/SmartTable/hooks/useTableColumns.ts","../src/components/SmartTable/index.vue","../src/components/SmartTable/config.ts","../src/types/enhanced.ts"],"sourcesContent":["/**\r\n * SmartTable 内部渲染器管理系统\r\n * 移动到组件内部,保证组件的自包含性\r\n */\r\nimport { defineComponent, h, Component } from 'vue'\r\nimport type { Renderer } from './types'\r\n\r\n/**\r\n * 渲染器注册表接口\r\n */\r\nexport interface RendererRegistry {\r\n register(name: string, renderer: Renderer): void\r\n registerMultiple(renderers: Record<string, Renderer>): void\r\n get(name: string): Renderer | undefined\r\n has(name: string): boolean\r\n unregister(name: string): boolean\r\n clear(): void\r\n names(): string[]\r\n}\r\n\r\n/**\r\n * 渲染器管理器类\r\n */\r\nclass RendererManager implements RendererRegistry {\r\n private renderers: Map<string, Renderer> = new Map()\r\n\r\n register(name: string, renderer: Renderer): void {\r\n if (this.renderers.has(name)) {\r\n // 批量注册时不警告,只在单独注册时警告\r\n if (process.env.NODE_ENV === 'development') {\r\n console.debug(`[SmartTable] Renderer \"${name}\" already registered, skipping.`)\r\n }\r\n }\r\n this.renderers.set(name, renderer)\r\n }\r\n\r\n registerMultiple(renderers: Record<string, Renderer>): void {\r\n Object.entries(renderers).forEach(([name, renderer]) => {\r\n if (!this.renderers.has(name)) {\r\n this.renderers.set(name, renderer)\r\n }\r\n })\r\n }\r\n\r\n get(name: string): Renderer | undefined {\r\n return this.renderers.get(name)\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.renderers.has(name)\r\n }\r\n\r\n unregister(name: string): boolean {\r\n return this.renderers.delete(name)\r\n }\r\n\r\n clear(): void {\r\n this.renderers.clear()\r\n }\r\n\r\n names(): string[] {\r\n return Array.from(this.renderers.keys())\r\n }\r\n}\r\n\r\n/**\r\n * 全局渲染器管理器单例\r\n */\r\nlet globalRendererManager: RendererManager | null = null\r\n\r\n/**\r\n * 获取渲染器管理器\r\n */\r\nexport function getRendererManager(): RendererManager {\r\n if (!globalRendererManager) {\r\n globalRendererManager = new RendererManager()\r\n }\r\n return globalRendererManager\r\n}\r\n\r\n/**\r\n * 包装 SFC 组件为渲染器\r\n */\r\nexport function wrapSFCComponent(comp: Component): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'onCellChange', 'onCellBlur', 'onCellEnter', 'onClick'],\r\n setup(props) {\r\n return () => h(comp, props)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 创建函数式渲染器\r\n */\r\nexport function createFunctionalRenderer(\r\n render: (props: {\r\n row: any\r\n col: any\r\n onCellChange?: (row: any, col: any) => void\r\n onCellBlur?: (row: any, col: any) => void\r\n onCellEnter?: (row: any, col: any) => void\r\n onClick?: (row: any, col: any) => void\r\n }) => any\r\n): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'onCellChange', 'onCellBlur', 'onCellEnter', 'onClick'],\r\n setup(props) {\r\n return () => render(props)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 验证渲染器配置\r\n * 在开发环境下验证 renderProps 的正确性\r\n */\r\nexport function validateRendererProps(\r\n rendererName: string,\r\n renderProps: Record<string, any> | undefined\r\n): void {\r\n if (process.env.NODE_ENV !== 'production' && renderProps) {\r\n switch (rendererName) {\r\n case 'dict':\r\n if (!renderProps.options || !Array.isArray(renderProps.options)) {\r\n console.warn(\r\n `[SmartTable] 'dict' renderer requires 'options' array, received:`,\r\n renderProps.options\r\n )\r\n }\r\n break\r\n\r\n case 'select':\r\n if (!renderProps.options || !Array.isArray(renderProps.options)) {\r\n console.warn(\r\n `[SmartTable] 'select' renderer requires 'options' array, received:`,\r\n renderProps.options\r\n )\r\n } else if (renderProps.options.length === 0) {\r\n console.warn(`[SmartTable] 'select' renderer 'options' array is empty`)\r\n }\r\n break\r\n\r\n case 'map':\r\n if (!renderProps.options || typeof renderProps.options !== 'object') {\r\n console.warn(\r\n `[SmartTable] 'map' renderer requires 'options' object, received:`,\r\n renderProps.options\r\n )\r\n }\r\n break\r\n\r\n case 'link':\r\n if (!renderProps.href || typeof renderProps.href !== 'string') {\r\n console.warn(\r\n `[SmartTable] 'link' renderer requires 'href' string, received:`,\r\n renderProps.href\r\n )\r\n }\r\n break\r\n\r\n case 'input-number':\r\n if (renderProps.min !== undefined && renderProps.max !== undefined) {\r\n if (renderProps.min > renderProps.max) {\r\n console.warn(\r\n `[SmartTable] 'input-number' renderer: min (${renderProps.min}) should not be greater than max (${renderProps.max})`\r\n )\r\n }\r\n }\r\n break\r\n }\r\n }\r\n}\r\n","/**\r\n * 安全获取对象深层属性\r\n * 支持 a.b.c / a.0.b\r\n */\r\nexport function getValueByPath(obj: any, path?: string) {\r\n if (!obj || !path) return undefined\r\n return path.split('.').reduce((acc, key) => acc?.[key], obj)\r\n }\r\n \r\n /**\r\n * 安全设置对象深层属性(用于可编辑表格)\r\n */\r\n export function setValueByPath(\r\n obj: any,\r\n path: string,\r\n value: any\r\n ) {\r\n if (!obj || !path) return\r\n const keys = path.split('.')\r\n const lastKey = keys.pop()!\r\n \r\n const target = keys.reduce((acc, key) => {\r\n if (!acc[key]) acc[key] = {}\r\n return acc[key]\r\n }, obj)\r\n \r\n target[lastKey] = value\r\n }\r\n ","<template>\n <el-input\n v-model=\"value\"\n v-bind=\"{ placeholder: '', size: 'small', clearable: true, ...col.renderProps }\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","<template>\n <el-input-number\n v-model=\"value\"\n v-bind=\"{ min: 0, max: 99999, controls: false, size: 'small', ...col.renderProps }\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellChange?: (row: any, col: ColumnConfig) => void\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n props.onCellChange?.(props.row, props.col)\n})\n\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","<template>\n <el-select\n v-model=\"value\"\n v-bind=\"{ placeholder: '请选择', size: 'small', clearable: true, ...col.renderProps }\"\n @change=\"onChange\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n >\n <el-option\n v-for=\"opt in col.renderProps?.options || []\"\n :key=\"opt.value\"\n :label=\"opt.label\"\n :value=\"opt.value\"\n />\n </el-select>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellChange?: (row: any, col: ColumnConfig) => void\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onChange = () => props.onCellChange?.(props.row, props.col)\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","/**\r\n * 内置渲染器集合\r\n * 可以按需引入或批量注册\r\n */\r\nimport { h } from 'vue'\r\nimport { ElButton, ElTag, ElImage, ElMessage } from 'element-plus'\r\nimport { DocumentCopy, CopyDocument } from '@element-plus/icons-vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getValueByPath } from '../utils/path'\r\nimport { wrapSFCComponent, createFunctionalRenderer } from '../renderer'\r\nimport EditableInput from './input.vue'\r\nimport EditableNumber from './inputNumber.vue'\r\nimport EditableSelect from './select.vue'\r\n\r\n/**\r\n * 包装 SFC 组件\r\n */\r\nconst input = wrapSFCComponent(EditableInput)\r\nconst inputNumber = wrapSFCComponent(EditableNumber)\r\nconst select = wrapSFCComponent(EditableSelect)\r\n\r\n/**\r\n * button 渲染器\r\n */\r\nconst button = createFunctionalRenderer((props) => {\r\n const rp = props.col.renderProps || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h(ElButton as any, {\r\n type: rp.type || 'primary',\r\n ...rp,\r\n onClick: () => props.onClick?.(props.row, props.col)\r\n }, () => rp.label || val)\r\n})\r\n\r\n/**\r\n * link 渲染器\r\n */\r\nconst link = createFunctionalRenderer((props) => {\r\n const rp = props.col.renderProps || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h('a', {\r\n href: rp.href || '#',\r\n target: rp.blank ? '_blank' : '_self',\r\n style: rp.style || 'color:#409EFF;cursor:pointer;',\r\n }, rp.label || val)\r\n})\r\n\r\n/**\r\n * html 渲染器\r\n */\r\nconst html = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h('div', {\r\n class: 'line-clamp-2',\r\n innerHTML: val ?? '',\r\n ...(props.col?.renderProps || {})\r\n })\r\n})\r\n\r\n/**\r\n * copy 渲染器\r\n */\r\nconst copy = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps ?? {}\r\n const butStyle = {\r\n 'position': 'absolute',\r\n 'right': '-5px',\r\n 'top': '50%',\r\n 'transform': 'translateY(-50%)',\r\n 'cursor': 'pointer',\r\n 'display': 'none',\r\n 'font-size': '12px',\r\n 'color': rp.iconColor || '#409EFF',\r\n 'user-select': 'none'\r\n }\r\n return h('div', {\r\n class: 'st_copy_wrapper',\r\n style: 'width: 100%; position: relative; display: inline-block;'\r\n },\r\n [\r\n h('span', {\r\n class: 'st_copy_text line-clamp-1',\r\n style: 'padding-right: 10px; display: block;',\r\n }, val),\r\n val && h('span', {\r\n class: 'st_copy_btn',\r\n style: butStyle,\r\n title: rp.copyTitle || '复制',\r\n onClick: () => {\r\n if (!val) return\r\n try {\r\n if (navigator.clipboard && navigator.clipboard.writeText) {\r\n navigator.clipboard.writeText(val).then(() => {\r\n ElMessage.success(rp.successText ?? '复制成功')\r\n }).catch(() => {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n })\r\n } else {\r\n const textarea = document.createElement('textarea')\r\n textarea.value = val\r\n textarea.style.position = 'fixed'\r\n textarea.style.opacity = '0'\r\n document.body.appendChild(textarea)\r\n textarea.select()\r\n const successful = document.execCommand('copy')\r\n document.body.removeChild(textarea)\r\n\r\n if (successful) {\r\n ElMessage.success(rp.successText ?? '复制成功')\r\n } else {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n }\r\n }\r\n } catch (err) {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n }\r\n }\r\n }, [h(DocumentCopy, {\r\n style: 'width: 1em; height: 1em;'\r\n })])\r\n ].filter(Boolean)\r\n )\r\n})\r\n\r\n/**\r\n * img 渲染器\r\n */\r\nconst img = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col?.renderProps || {}\r\n\r\n const getImageList = () => {\r\n if (!val) return []\r\n if (Array.isArray(val)) {\r\n return val.filter(item => item && typeof item === 'string')\r\n }\r\n return [val]\r\n }\r\n\r\n const imageList = getImageList()\r\n\r\n if (imageList.length === 0) {\r\n return rp.placeholder || ''\r\n }\r\n\r\n const defaultStyle = {\r\n width: rp.width || '80px',\r\n height: rp.height || '80px',\r\n marginRight: imageList.length > 1 ? '4px' : '0',\r\n ...(rp.style || {})\r\n }\r\n\r\n if (imageList.length === 1) {\r\n return h(ElImage, {\r\n src: imageList[0],\r\n previewSrcList: rp.previewSrcList || imageList,\r\n fit: rp.fit || 'contain',\r\n style: defaultStyle,\r\n ...rp\r\n })\r\n }\r\n\r\n return h('div',\r\n {\r\n class: 'st_img_wrapper',\r\n style: 'display: flex; align-items: center; position: relative'\r\n },\r\n [\r\n h(ElImage, {\r\n src: imageList[0],\r\n previewSrcList: rp.previewSrcList || imageList,\r\n fit: rp.fit || 'contain',\r\n style: defaultStyle,\r\n ...rp\r\n }),\r\n imageList.length > 1 && h('span', {\r\n class: 'st_img_total',\r\n style: `position: absolute; top: 0; right: 0; `,\r\n title: `${imageList.length}`\r\n }, [h(CopyDocument, { style: `width: 1em; height: 1em; ` })])\r\n ]\r\n )\r\n})\r\n\r\n/**\r\n * dict 渲染器\r\n */\r\nconst dict = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps || {}\r\n const options = rp.options ?? []\r\n const showValue = rp.showValue ?? false\r\n\r\n if (val === null || val === undefined || val === '') return ''\r\n\r\n const values = Array.isArray(val) ? val.map(String) : [String(val)]\r\n const matchedOptions = options.filter((opt: any) => values.includes(String(opt.value)))\r\n const unmatched = values.filter(v => !options.some((opt: any) => String(opt.value) === v))\r\n\r\n const children = matchedOptions.map((item: any, _index: number) => {\r\n return h(\r\n ElTag,\r\n { key: item.value, type: item.listClass, class: item.cssClass, disableTransitions: true },\r\n { default: () => item.label + ' ' }\r\n )\r\n })\r\n\r\n if (showValue && unmatched.length > 0) {\r\n children.push(h('span', {}, unmatched.join(' ')))\r\n }\r\n\r\n return h('div', {}, children)\r\n})\r\n\r\n/**\r\n * map 渲染器\r\n */\r\nconst map = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const options = (props.col.renderProps?.options ?? {}) as Record<string, any>\r\n return val != null ? options[val] ?? '' : ''\r\n})\r\n\r\n/**\r\n * formatter 渲染器\r\n */\r\nexport function isDataColumn(\r\n col: ColumnConfig\r\n): col is any {\r\n return typeof (col as any).formatter === 'function'\r\n}\r\n\r\nconst formatter = createFunctionalRenderer((props) => {\r\n const { col, row } = props\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n if (isDataColumn(col)) {\r\n return col.formatter?.(val, row)\r\n }\r\n return val ?? ''\r\n})\r\n\r\n/**\r\n * icon 渲染器\r\n */\r\nconst icon = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps || {}\r\n if (!val) return ''\r\n // 判断网络图片\r\n if (/^https?:\\/\\//.test(val)) {\r\n return h(ElImage, {\r\n src: val,\r\n previewSrcList: [val],\r\n fit: 'contain',\r\n style: 'width:40px;height:40px',\r\n ...rp\r\n })\r\n }\r\n // 判断 svg 源码\r\n if (/^\\s*<svg[\\s\\S]*<\\/svg>\\s*$/.test(val)) {\r\n return h('div', {\r\n innerHTML: val,\r\n style: `width:40px;height:40px;display:inline-block;${rp.style || ''}`,\r\n ...rp\r\n })\r\n }\r\n // 默认当作 iconfont\r\n return h('i', {\r\n class: val,\r\n style: `font-size:20px;${rp.style || ''}`,\r\n ...rp\r\n })\r\n})\r\n\r\n/**\r\n * 所有内置渲染器\r\n */\r\nexport const builtInRenderers = {\r\n input,\r\n 'input-number': inputNumber,\r\n select,\r\n button,\r\n link,\r\n html,\r\n copy,\r\n img,\r\n dict,\r\n map,\r\n formatter,\r\n icon,\r\n}\r\n\r\n/**\r\n * 安装所有内置渲染器\r\n */\r\nexport function registerBuiltInRenderers(registry: { registerMultiple: (renderers: Record<string, any>) => void }) {\r\n registry.registerMultiple(builtInRenderers)\r\n}\r\n\r\n/**\r\n * 创建默认渲染器集合(兼容旧 API)\r\n * @deprecated 建议使用插件化架构\r\n */\r\nexport function createRenderer() {\r\n return builtInRenderers\r\n}\r\n","import { computed } from 'vue'\r\n\r\nimport { ButtonConfig } from \"../types\"\r\n/**\r\n * useOperationColumn\r\n *\r\n * 操作列专用逻辑 Hook,负责:\r\n * 1. 根据权限判断操作列是否需要显示\r\n * 2. 计算操作列宽度(支持按钮自定义宽度)\r\n * 3. 支持行级 visible 配置\r\n * @param buttonConfigs 操作列按钮配置\r\n * @param maxbtn 操作列最多显示按钮数量(超过的不参与宽度计算)\r\n * @param userPermissions 当前用户权限列表\r\n */\r\nexport function useOperationColumn(\r\n buttonConfigs: ButtonConfig[],\r\n maxbtn = 10,\r\n userPermissions: string[] = []\r\n) {\r\n /** 默认按钮宽度 */\r\n const defaultWidth = 60\r\n\r\n /** 超级权限标识 */\r\n const all_permission = '*:*:*'\r\n\r\n /** --------------------------\r\n * 权限判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断是否具备按钮权限\r\n *\r\n * 规则:\r\n * - permission 未配置 ⇒ 永远有权限\r\n * - permission 为 string | string[] ⇒ 与用户权限匹配\r\n */\r\n const hasPermi = (value?: string | string[]) => {\r\n if (!value) return true\r\n\r\n const permArray = Array.isArray(value) ? value : [value]\r\n return userPermissions.some(\r\n p => p === all_permission || permArray.includes(p)\r\n )\r\n }\r\n\r\n /** --------------------------\r\n * 仅基于权限(不考虑行级 visible)\r\n * 适用于:表格未加载数据时的判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 是否至少存在一个有权限的按钮\r\n * 用于判断操作列是否需要渲染\r\n */\r\n const hasAnyButton = computed(() => {\r\n return buttonConfigs.some(btn => hasPermi(btn.permission))\r\n })\r\n\r\n /**\r\n * 操作列宽度(仅基于权限)\r\n * 用于无行数据时的兜底宽度计算\r\n */\r\n const optWidth = computed(() => {\r\n const permittedBtns = buttonConfigs\r\n .filter(btn => hasPermi(btn.permission))\r\n .slice(0, maxbtn)\r\n\r\n return permittedBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n })\r\n\r\n /** --------------------------\r\n * 权限 + 行级 visible\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断某个按钮在某一行是否可见\r\n */\r\n const isButtonVisible = (btn: ButtonConfig, row: any) => {\r\n return (\r\n hasPermi(btn.permission) &&\r\n (btn.visible ? btn.visible(row) : true)\r\n )\r\n }\r\n\r\n /**\r\n * 单行操作列宽度\r\n */\r\n const optRowWidth = (row: any) => {\r\n const visibleBtns = buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n\r\n return visibleBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 遍历所有行,获取最大操作列宽度\r\n */\r\n const getMaxOptWidth = (rows: any[]) => {\r\n if (!rows?.length) return optWidth.value\r\n return rows.reduce(\r\n (max, row) => Math.max(max, optRowWidth(row)),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 判断是否至少有一行存在可见按钮\r\n */\r\n const hasAnyVisibleButton = (rows: any[]) => {\r\n if (!rows?.length) return false\r\n return rows.some(row =>\r\n buttonConfigs.some(btn => isButtonVisible(btn, row))\r\n )\r\n }\r\n\r\n const getVisibleButtons = (row: any) => {\r\n return buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n }\r\n\r\n return {\r\n hasAnyButton,\r\n optWidth,\r\n hasAnyVisibleButton,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n }\r\n}\r\n","<template>\r\n <!-- ========== selection 列 ========== -->\r\n <el-table-column\r\n v-if=\"col.type === 'selection'\"\r\n type=\"selection\"\r\n v-bind=\"col.columnProps\"\r\n />\r\n\r\n <!-- ========== index 列 ========== -->\r\n <el-table-column\r\n v-else-if=\"col.type === 'index'\"\r\n type=\"index\"\r\n :label=\"col.label || '#'\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps\"\r\n >\r\n <template #default=\"{ $index }\">\r\n {{ computeIndex($index) }}\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== operation 列 ========== -->\r\n <el-table-column\r\n v-else-if=\"col.type === 'operation' && showOperationColumn\"\r\n :label=\"col.label || '操作'\"\r\n align=\"center\"\r\n v-bind=\"{\r\n ...col.columnProps,\r\n width: operationWidth\r\n }\"\r\n >\r\n <template #default=\"{ row }\">\r\n <el-button\r\n v-for=\"btn in getVisibleButtons(row)\"\r\n :key=\"btn.label\"\r\n :type=\"btn.type || 'primary'\"\r\n link\r\n @click=\"btn.action(row)\"\r\n >\r\n {{ btn.label }}\r\n </el-button>\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== 普通列 / renderer / editable ========== -->\r\n <el-table-column\r\n v-else-if=\"isDataOrOperationColumn(col)\"\r\n :label=\"col.label\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps || {}\"\r\n >\r\n \r\n <template #default=\"scope\">\r\n <!-- 父组件插槽优先 -->\r\n <template v-if=\"col.render === 'slot' && $slots[col?.slot || col.key]\">\r\n <slot :name=\"col?.slot || col.key\" v-bind=\"scope\" />\r\n </template>\r\n\r\n <!-- renderer -->\r\n <component\r\n v-else-if=\"col.render && renderer[col.render]\"\r\n :is=\"renderer[col.render]\"\r\n :row=\"scope.row\"\r\n :col=\"col\"\r\n :onCellChange=\"handleCellChange\"\r\n :onCellBlur=\"handleCellBlur\"\r\n :onCellEnter=\"handleCellEnter\"\r\n :onClick=\"handleCellClick\"\r\n />\r\n <!-- 默认文本 -->\r\n <span v-else\r\n :style=\"col.renderProps?.style || ''\"\r\n :class=\"col.renderProps?.class || ''\"\r\n :title=\"getValueByPath(scope.row, col.key)\">\r\n {{ getValueByPath(scope.row, col.key) }}\r\n </span>\r\n </template>\r\n </el-table-column>\r\n \r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, toRefs } from 'vue'\r\nimport type { PropType } from 'vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getRendererManager } from '../renderer'\r\nimport { registerBuiltInRenderers } from '../renderers'\r\nimport { useOperationColumn } from '../hooks/useOperationColumn'\r\nimport { getValueByPath } from '../utils/path'\r\n\r\nconst props = defineProps({\r\n col: { type: Object as PropType<ColumnConfig>, required: true },\r\n permissions: { type: Array as PropType<string[]>, default: () => [] },\r\n pagination: { type: Object, default: () => ({}) },\r\n})\r\n\r\nconst emit = defineEmits(['cellBlur', 'cellEnter', 'cellChange', 'cellClick'])\r\n\r\nconst computeIndex = (index: number) => {\r\n const page = props.pagination?.page\r\n const size = props.pagination?.size\r\n return page && size ? (page - 1) * size + index + 1 : index + 1\r\n}\r\n\r\n/** 解构 col 响应式引用 */\r\nconst { col } = toRefs(props)\r\n\r\n/** ========== 事件统一上抛 ========== */\r\nconst handleCellChange = (row: any, key: string) => emit('cellChange', row, key)\r\nconst handleCellBlur = (row: any, key: string) => emit('cellBlur', row, key)\r\nconst handleCellEnter = (row: any, key: string) => emit('cellEnter', row, key)\r\nconst handleCellClick = (row: any, col: any) => emit('cellClick', row, col)\r\n\r\n/** ========== renderer 注册 ========== */\r\n// 注册内置渲染器(重复调用会自动跳过已存在的)\r\nregisterBuiltInRenderers(getRendererManager())\r\n\r\n// 获取所有渲染器(内置 + 自定义)\r\nconst renderer = computed(() => {\r\n const manager = getRendererManager()\r\n const allRenderers: Record<string, any> = {}\r\n\r\n // 合并内置渲染器和自定义渲染器\r\n manager.names().forEach((name: string) => {\r\n const r = manager.get(name)\r\n if (r) allRenderers[name] = r\r\n })\r\n\r\n return allRenderers\r\n})\r\n\r\n/** ========== operation 列逻辑 ========== */\r\nconst {\r\n hasAnyButton,\r\n hasAnyVisibleButton,\r\n optWidth,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n} = useOperationColumn(\r\n col.value.buttons || [],\r\n col.value.maxbtn ?? 10,\r\n props.permissions || []\r\n)\r\n\r\n/** 是否显示操作列 */\r\nconst showOperationColumn = computed(() => {\r\n const buttons = col.value.buttons || []\r\n if (!buttons.length) return false // 没有配置按钮直接隐藏\r\n const rows = col.value.__rows || []\r\n // 无行数据时,至少有一个按钮有权限就显示\r\n if (!rows.length) return hasAnyButton.value\r\n // 有行数据时,至少一行有可见按钮才显示\r\n return hasAnyVisibleButton(col.value.__rows || [])\r\n})\r\n\r\n/** 操作列宽度 */\r\nconst operationWidth = computed(() => {\r\n // 无行数据,用静态宽度\r\n if (!col.value.__rows) return optWidth.value\r\n // 有行数据,取最大宽度\r\n return getMaxOptWidth(col.value.__rows)\r\n})\r\n\r\nfunction isDataOrOperationColumn(c: ColumnConfig) {\r\n if (c.type === 'selection' || c.type === 'index') return false\r\n if (c.type === 'operation' && !showOperationColumn.value) return false\r\n if (c.visible === false) return false\r\n return true\r\n}\r\n</script>","import { ref, watch } from 'vue'\r\n\r\n\r\n/**\r\n * 合并默认列配置和缓存配置\r\n *\r\n * 设计原则:\r\n * 1️⃣ 列顺序:以 defaultColumns 为准\r\n * 2️⃣ 列增减:以 defaultColumns 为准\r\n * 3️⃣ 缓存只覆盖用户可配置字段(如 visible)\r\n */\r\nfunction mergeColumns(\r\n defaultColumns: any[],\r\n cacheColumns: Array<{ key: string; visible?: boolean }>\r\n) {\r\n if (!cacheColumns?.length) return defaultColumns\r\n\r\n // 建立 key => cache 映射表,提升查找效率\r\n const cacheMap = new Map(\r\n cacheColumns.map(c => [c.key, c])\r\n )\r\n\r\n return defaultColumns.map(col => {\r\n const cacheCol = cacheMap.get(col.key)\r\n\r\n // 只允许缓存覆盖「可配置字段」\r\n if (!cacheCol) return col\r\n\r\n return {\r\n ...col,\r\n visible:\r\n typeof cacheCol.visible === 'boolean'\r\n ? cacheCol.visible\r\n : col.visible\r\n }\r\n })\r\n}\r\n\r\n\r\n/**\r\n * useTableColumns\r\n *\r\n * 表格列管理 Hook\r\n *\r\n * 职责:\r\n * - 管理表格列顺序\r\n * - 管理列显示 / 隐藏\r\n * - 持久化用户配置\r\n */\r\nexport function useTableColumns(\r\n defaultColumns: any[],\r\n options?: {\r\n /** 缓存唯一标识 */\r\n cacheKey?: string\r\n /** 存储介质,默认 localStorage */\r\n storage?: Storage\r\n }\r\n) {\r\n\r\n /** 解构参数并设置默认值 */\r\n const { cacheKey, storage = localStorage } = options || {}\r\n\r\n /**\r\n * 如果没有 cacheKey,则不启用缓存\r\n * (例如公共页面、未登录页面)\r\n * 从缓存中读取列配置\r\n */\r\n const cache = cacheKey ? storage.getItem(cacheKey) : null\r\n\r\n /**\r\n * 响应式列配置\r\n * 初始化时合并默认列和缓存列\r\n */\r\n const columns = ref(\r\n mergeColumns(\r\n defaultColumns,\r\n cache ? JSON.parse(cache) : []\r\n )\r\n )\r\n\r\n /**\r\n * 监听列变化,自动写入缓存\r\n */\r\n watch(\r\n columns,\r\n (newVal: any) => {\r\n if (!cacheKey) return\r\n\r\n /**\r\n * ⚠️ 只保存“轻量配置”\r\n * 避免把 render / action / 函数序列化进 localStorage\r\n */\r\n const lightColumns = newVal.map((col: any) => ({\r\n key: col.key,\r\n visible: col.visible,\r\n columnOpts: col.columnOpts\r\n }))\r\n\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(lightColumns)\r\n )\r\n },\r\n { deep: true }\r\n )\r\n\r\n /**\r\n * 对外暴露的 API\r\n */\r\n return {\r\n /** 当前列配置(响应式) */\r\n columns,\r\n\r\n /**\r\n * 主动设置列配置\r\n * 常用于:列设置弹窗 / 拖拽排序完成\r\n */\r\n setColumns(newColumns: any[]) {\r\n columns.value = mergeColumns(\r\n defaultColumns,\r\n newColumns\r\n )\r\n\r\n if (cacheKey) {\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(newColumns)\r\n )\r\n }\r\n },\r\n\r\n /**\r\n * 重置为默认列配置\r\n */\r\n resetColumns() {\r\n columns.value = defaultColumns\r\n\r\n if (cacheKey) {\r\n storage.removeItem(cacheKey)\r\n }\r\n }\r\n }\r\n}\r\n","<template>\r\n <el-table ref=\"tableRef\"\r\n v-bind=\"$attrs\"\r\n :data=\"data\"\r\n :row-key=\"rowKey\"\r\n class=\"smart_table\"\r\n v-loading=\"loading\">\r\n <TableColumn \r\n v-for=\"col in cachedColumns\" \r\n :key=\"col.key\" \r\n :col=\"col\" \r\n :permissions=\"permissions\"\r\n :pagination=\"pagination\"\r\n @cell-change=\"handleCellChange\"\r\n @cell-blur=\"handleCellBlur\"\r\n @cell-enter=\"handleCellEnter\"\r\n @cell-click=\"handleCellClick\">\r\n <template v-for=\"col in cachedColumns\" #[col.key]=\"slotProps\">\r\n <slot :name=\"col.key\" v-bind=\"slotProps\" />\r\n </template>\r\n </TableColumn>\r\n </el-table>\r\n</template>\r\n\r\n<script setup lang=\"ts\" name=\"SmartTable\">\r\n import { PropType, ref, watch } from 'vue'\r\n import TableColumn from './column/index.vue'\r\n import type { BaseColumn, ColumnConfig } from './types'\r\n import { useTableColumns } from \"./hooks/useTableColumns\"\r\n\r\n const props = defineProps({\r\n data: { type: Array, default: () => [] },\r\n columns: { type: Array, default: () => [] },\r\n rowKey: { type: String, default: 'id' },\r\n loading: { type: Boolean, default: false },\r\n permissions: {\r\n type: Array as PropType<string[]>,\r\n default: () => []\r\n },\r\n cacheKey: String,\r\n pagination: { type: Object, default: () => ({}) },\r\n\r\n })\r\n \r\n const emit = defineEmits([\r\n 'update:columns',\r\n 'cellChange',\r\n 'cellBlur',\r\n 'cellEnter',\r\n 'cell-click',\r\n ])\r\n\r\n // ------------------ columns 处理 ------------------\r\n const { columns: cachedColumns } = useTableColumns(props.columns, {\r\n cacheKey: props.cacheKey ?? '',\r\n })\r\n watch(\r\n cachedColumns,\r\n (val: ColumnConfig[]) => emit(\"update:columns\", val),\r\n { deep: true, immediate: true },\r\n )\r\n\r\n // ----------------事件封装 ------------------\r\n const handleCellChange = (row: any, key: string) => emit('cellChange', row, key)\r\n const handleCellBlur = (row: any, key: string) => {\r\n emit('cellBlur', row, key)\r\n }\r\n const handleCellEnter = (row: any, key: string) => {\r\n console.log('enter')\r\n emit('cellEnter', row, key)\r\n }\r\n \r\n // SmartTable\r\n const handleCellClick = (row: any, col: any) => {\r\n if(!col) return\r\n emit('cell-click', row, col)\r\n }\r\n\r\n // el-table\r\n const tableRef = ref();\r\n defineExpose({\r\n tableRef,\r\n });\r\n\r\n</script>\r\n\r\n<style>\r\n .smart_table {\r\n width: 100%;\r\n }\r\n \r\n .st_copy_wrapper:hover .st_copy_btn {\r\n display: inline-block !important;\r\n }\r\n\r\n .st_copy_btn:hover {\r\n transform: translateY(-50%) scale(1.1);\r\n }\r\n</style>\r\n","/**\r\n * 全局配置管理\r\n */\r\nimport type { SmartTableConfig } from './types'\r\nimport { getRendererManager } from './renderer'\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst defaultConfig: SmartTableConfig = {\r\n defaultPagination: {\r\n page: 1,\r\n size: 10,\r\n total: 0\r\n },\r\n defaultTableProps: {},\r\n defaultColumnProps: {}\r\n}\r\n\r\n/**\r\n * 全局配置类\r\n */\r\nclass ConfigManager {\r\n private config: SmartTableConfig = { ...defaultConfig }\r\n\r\n /**\r\n * 获取所有配置\r\n */\r\n getConfig(): SmartTableConfig {\r\n return { ...this.config }\r\n }\r\n\r\n /**\r\n * 设置配置\r\n */\r\n setConfig(config: Partial<SmartTableConfig>): void {\r\n this.config = this.mergeConfig(this.config, config)\r\n\r\n // 如果有自定义渲染器,自动注册\r\n if (config.renderers) {\r\n const manager = getRendererManager()\r\n manager.registerMultiple(config.renderers)\r\n }\r\n }\r\n\r\n /**\r\n * 获取特定配置项\r\n */\r\n get<K extends keyof SmartTableConfig>(key: K): SmartTableConfig[K] {\r\n return this.config[key]\r\n }\r\n\r\n /**\r\n * 重置为默认配置\r\n */\r\n reset(): void {\r\n this.config = { ...defaultConfig }\r\n }\r\n\r\n /**\r\n * 深度合并配置\r\n */\r\n private mergeConfig(target: any, source: any): any {\r\n const result = { ...target }\r\n\r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n result[key] = this.mergeConfig(target[key] || {}, source[key])\r\n } else {\r\n result[key] = source[key]\r\n }\r\n }\r\n\r\n return result\r\n }\r\n}\r\n\r\n/**\r\n * 全局配置管理器单例\r\n */\r\nlet globalConfigManager: ConfigManager | null = null\r\n\r\n/**\r\n * 获取全局配置管理器\r\n */\r\nexport function getConfigManager(): ConfigManager {\r\n if (!globalConfigManager) {\r\n globalConfigManager = new ConfigManager()\r\n }\r\n return globalConfigManager\r\n}\r\n\r\n/**\r\n * 安装插件(用于 Vue.use())\r\n */\r\nexport interface SmartTablePlugin {\r\n install: (options?: SmartTableConfig) => void\r\n}\r\n\r\n/**\r\n * 创建插件实例\r\n */\r\nexport function createSmartTablePlugin(defaultOptions?: SmartTableConfig): SmartTablePlugin {\r\n return {\r\n install(options?: SmartTableConfig) {\r\n const manager = getConfigManager()\r\n const config = { ...defaultOptions, ...options }\r\n if (config) {\r\n manager.setConfig(config)\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 全局配置快捷方法\r\n */\r\nexport function setSmartTableConfig(config: Partial<SmartTableConfig>): void {\r\n getConfigManager().setConfig(config)\r\n}\r\n\r\nexport function getSmartTableConfig(): SmartTableConfig {\r\n return getConfigManager().getConfig()\r\n}\r\n","/**\r\n * 增强类型系统 - 提供更好的类型推断\r\n */\r\nimport type { ColumnConfig, RendererName } from '../components/SmartTable/types'\r\n\r\n/**\r\n * 提取行数据的类型\r\n */\r\nexport type ExtractRowType<T> = T extends ColumnConfig<infer R> ? R : never\r\n\r\n/**\r\n * 根据列配置提取表格数据类型\r\n */\r\nexport type TableDataFromColumns<T extends ColumnConfig[]> = T extends (infer C)[]\r\n ? C extends ColumnConfig<infer R>\r\n ? R\r\n : any\r\n : any\r\n\r\n/**\r\n * 渲染器 Props 类型推断\r\n */\r\nexport type InferRendererProps<T extends RendererName> =\r\n T extends 'html'\r\n ? { style?: string; class?: string; [key: string]: any }\r\n : T extends 'copy'\r\n ? { successText?: string; errorText?: string; iconColor?: string; [key: string]: any }\r\n : T extends 'img'\r\n ? { width?: string | number; height?: string | number; fit?: string; previewSrcList?: string[]; [key: string]: any }\r\n : T extends 'dict'\r\n ? { options: Array<{ label: string; value: string | number; listClass?: string; cssClass?: string }>; showValue?: boolean }\r\n : T extends 'map'\r\n ? { options: Record<string | number, any> }\r\n : T extends 'input'\r\n ? { placeholder?: string; size?: 'small' | 'default' | 'large'; clearable?: boolean }\r\n : T extends 'select'\r\n ? { options: Array<{ label: string; value: string | number }>; placeholder?: string; clearable?: boolean }\r\n : { [key: string]: any }\r\n\r\n/**\r\n * 快捷创建列的辅助函数(类型安全简化版)\r\n */\r\nexport function defineColumn(\r\n key: string,\r\n config?: Partial<Omit<ColumnConfig, 'key'>>\r\n): ColumnConfig {\r\n return {\r\n key,\r\n ...config\r\n } as ColumnConfig\r\n}\r\n"],"names":["RendererManager","__publicField","name","renderer","renderers","globalRendererManager","getRendererManager","wrapSFCComponent","comp","defineComponent","props","h","createFunctionalRenderer","render","validateRendererProps","rendererName","renderProps","getValueByPath","obj","path","acc","key","setValueByPath","value","keys","lastKey","target","__props","ref","watch","v","onBlur","_a","onEnter","_openBlock","_createBlock","_component_el_input","_mergeProps","$event","_component_el_input_number","onChange","_component_el_select","_createElementBlock","_Fragment","opt","_component_el_option","input","EditableInput","inputNumber","EditableNumber","select","EditableSelect","button","rp","val","ElButton","link","html","copy","butStyle","ElMessage","textarea","successful","DocumentCopy","img","imageList","item","defaultStyle","ElImage","CopyDocument","dict","options","showValue","values","matchedOptions","unmatched","children","_index","ElTag","map","isDataColumn","col","formatter","row","icon","builtInRenderers","registerBuiltInRenderers","registry","createRenderer","useOperationColumn","buttonConfigs","maxbtn","userPermissions","all_permission","hasPermi","permArray","hasAnyButton","computed","btn","optWidth","sum","isButtonVisible","optRowWidth","rows","max","emit","__emit","computeIndex","index","page","size","_b","toRefs","handleCellChange","handleCellBlur","handleCellEnter","handleCellClick","manager","allRenderers","r","hasAnyVisibleButton","getMaxOptWidth","getVisibleButtons","showOperationColumn","operationWidth","isDataOrOperationColumn","c","_unref","_component_el_table_column","_withCtx","$index","_createTextVNode","_toDisplayString","_renderList","_component_el_button","scope","$slots","_renderSlot","_ctx","_normalizeProps","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_hoisted_1","mergeColumns","defaultColumns","cacheColumns","cacheMap","cacheCol","useTableColumns","cacheKey","storage","cache","columns","newVal","lightColumns","newColumns","cachedColumns","tableRef","__expose","_withDirectives","_component_el_table","$attrs","TableColumn","slotProps","defaultConfig","ConfigManager","config","source","result","globalConfigManager","getConfigManager","setSmartTableConfig","getSmartTableConfig","defineColumn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vue3-smart-table.es.js","sources":["../src/components/SmartTable/renderer.ts","../src/components/SmartTable/utils/path.ts","../src/components/SmartTable/renderers/input.vue","../src/components/SmartTable/renderers/inputNumber.vue","../src/components/SmartTable/renderers/select.vue","../src/components/SmartTable/renderers/index.ts","../src/components/SmartTable/hooks/useOperationColumn.ts","../src/components/SmartTable/column/index.vue","../src/components/SmartTable/hooks/useTableColumns.ts","../src/components/SmartTable/index.vue","../src/components/SmartTable/config.ts","../src/types/enhanced.ts"],"sourcesContent":["/**\r\n * SmartTable 内部渲染器管理系统\r\n * 移动到组件内部,保证组件的自包含性\r\n */\r\nimport { defineComponent, h, Component } from 'vue'\r\nimport type { Renderer } from './types'\r\n\r\n/**\r\n * 渲染器注册表接口\r\n */\r\nexport interface RendererRegistry {\r\n register(name: string, renderer: Renderer): void\r\n registerMultiple(renderers: Record<string, Renderer>): void\r\n get(name: string): Renderer | undefined\r\n has(name: string): boolean\r\n unregister(name: string): boolean\r\n clear(): void\r\n names(): string[]\r\n}\r\n\r\n/**\r\n * 渲染器管理器类\r\n */\r\nclass RendererManager implements RendererRegistry {\r\n private renderers: Map<string, Renderer> = new Map()\r\n\r\n register(name: string, renderer: Renderer): void {\r\n if (this.renderers.has(name)) {\r\n // 批量注册时不警告,只在单独注册时警告\r\n if (process.env.NODE_ENV === 'development') {\r\n console.debug(`[SmartTable] Renderer \"${name}\" already registered, skipping.`)\r\n }\r\n }\r\n this.renderers.set(name, renderer)\r\n }\r\n\r\n registerMultiple(renderers: Record<string, Renderer>): void {\r\n Object.entries(renderers).forEach(([name, renderer]) => {\r\n if (!this.renderers.has(name)) {\r\n this.renderers.set(name, renderer)\r\n }\r\n })\r\n }\r\n\r\n get(name: string): Renderer | undefined {\r\n return this.renderers.get(name)\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.renderers.has(name)\r\n }\r\n\r\n unregister(name: string): boolean {\r\n return this.renderers.delete(name)\r\n }\r\n\r\n clear(): void {\r\n this.renderers.clear()\r\n }\r\n\r\n names(): string[] {\r\n return Array.from(this.renderers.keys())\r\n }\r\n}\r\n\r\n/**\r\n * 全局渲染器管理器单例\r\n */\r\nlet globalRendererManager: RendererManager | null = null\r\n\r\n/**\r\n * 获取渲染器管理器\r\n */\r\nexport function getRendererManager(): RendererManager {\r\n if (!globalRendererManager) {\r\n globalRendererManager = new RendererManager()\r\n }\r\n return globalRendererManager\r\n}\r\n\r\n/**\r\n * 包装 SFC 组件为渲染器\r\n */\r\nexport function wrapSFCComponent(comp: Component): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'onCellChange', 'onCellBlur', 'onCellEnter', 'onClick'],\r\n setup(props) {\r\n return () => h(comp, props)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 创建函数式渲染器\r\n */\r\nexport function createFunctionalRenderer(\r\n render: (props: {\r\n row: any\r\n col: any\r\n onCellChange?: (row: any, col: any) => void\r\n onCellBlur?: (row: any, col: any) => void\r\n onCellEnter?: (row: any, col: any) => void\r\n onClick?: (row: any, col: any) => void\r\n }) => any\r\n): Renderer {\r\n return defineComponent({\r\n props: ['row', 'col', 'onCellChange', 'onCellBlur', 'onCellEnter', 'onClick'],\r\n setup(props) {\r\n return () => render(props)\r\n }\r\n })\r\n}\r\n\r\n/**\r\n * 验证渲染器配置\r\n * 在开发环境下验证 renderProps 的正确性\r\n */\r\nexport function validateRendererProps(\r\n rendererName: string,\r\n renderProps: Record<string, any> | undefined\r\n): void {\r\n if (process.env.NODE_ENV !== 'production' && renderProps) {\r\n switch (rendererName) {\r\n case 'dict':\r\n if (!renderProps.options || !Array.isArray(renderProps.options)) {\r\n console.warn(\r\n `[SmartTable] 'dict' renderer requires 'options' array, received:`,\r\n renderProps.options\r\n )\r\n }\r\n break\r\n\r\n case 'select':\r\n if (!renderProps.options || !Array.isArray(renderProps.options)) {\r\n console.warn(\r\n `[SmartTable] 'select' renderer requires 'options' array, received:`,\r\n renderProps.options\r\n )\r\n } else if (renderProps.options.length === 0) {\r\n console.warn(`[SmartTable] 'select' renderer 'options' array is empty`)\r\n }\r\n break\r\n\r\n case 'map':\r\n if (!renderProps.options || typeof renderProps.options !== 'object') {\r\n console.warn(\r\n `[SmartTable] 'map' renderer requires 'options' object, received:`,\r\n renderProps.options\r\n )\r\n }\r\n break\r\n\r\n case 'link':\r\n if (!renderProps.href || typeof renderProps.href !== 'string') {\r\n console.warn(\r\n `[SmartTable] 'link' renderer requires 'href' string, received:`,\r\n renderProps.href\r\n )\r\n }\r\n break\r\n\r\n case 'input-number':\r\n if (renderProps.min !== undefined && renderProps.max !== undefined) {\r\n if (renderProps.min > renderProps.max) {\r\n console.warn(\r\n `[SmartTable] 'input-number' renderer: min (${renderProps.min}) should not be greater than max (${renderProps.max})`\r\n )\r\n }\r\n }\r\n break\r\n }\r\n }\r\n}\r\n","/**\r\n * 安全获取对象深层属性\r\n * 支持 a.b.c / a.0.b\r\n */\r\nexport function getValueByPath(obj: any, path?: string) {\r\n if (!obj || !path) return undefined\r\n return path.split('.').reduce((acc, key) => acc?.[key], obj)\r\n }\r\n \r\n /**\r\n * 安全设置对象深层属性(用于可编辑表格)\r\n */\r\n export function setValueByPath(\r\n obj: any,\r\n path: string,\r\n value: any\r\n ) {\r\n if (!obj || !path) return\r\n const keys = path.split('.')\r\n const lastKey = keys.pop()!\r\n \r\n const target = keys.reduce((acc, key) => {\r\n if (!acc[key]) acc[key] = {}\r\n return acc[key]\r\n }, obj)\r\n \r\n target[lastKey] = value\r\n }\r\n ","<template>\n <el-input\n v-model=\"value\"\n v-bind=\"{ placeholder: '', size: 'small', clearable: true, ...col.renderProps }\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","<template>\n <el-input-number\n v-model=\"value\"\n v-bind=\"{ min: 0, max: 99999, controls: false, size: 'small', ...col.renderProps }\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellChange?: (row: any, col: ColumnConfig) => void\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n props.onCellChange?.(props.row, props.col)\n})\n\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","<template>\n <el-select\n v-model=\"value\"\n v-bind=\"{ placeholder: '请选择', size: 'small', clearable: true, ...col.renderProps }\"\n @change=\"onChange\"\n @blur=\"onBlur\"\n @keyup.enter=\"onEnter\"\n >\n <el-option\n v-for=\"opt in col.renderProps?.options || []\"\n :key=\"opt.value\"\n :label=\"opt.label\"\n :value=\"opt.value\"\n />\n </el-select>\n</template>\n\n<script setup lang=\"ts\">\nimport { ref, watch } from 'vue'\nimport type { ColumnConfig } from '../types'\nimport { getValueByPath, setValueByPath } from '../utils/path'\n\ninterface Props {\n readonly row: any\n readonly col: ColumnConfig\n onCellChange?: (row: any, col: ColumnConfig) => void\n onCellBlur?: (row: any, col: ColumnConfig) => void\n onCellEnter?: (row: any, col: ColumnConfig) => void\n}\n\nconst props = defineProps<Props>()\nconst value = ref(getValueByPath(props.row, props.col.key))\n\nwatch(value, (v) => {\n setValueByPath(props.row, props.col.key, v)\n})\n\nconst onChange = () => props.onCellChange?.(props.row, props.col)\nconst onBlur = () => props.onCellBlur?.(props.row, props.col)\nconst onEnter = () => props.onCellEnter?.(props.row, props.col)\n</script>\n","/**\r\n * 内置渲染器集合\r\n * 可以按需引入或批量注册\r\n */\r\nimport { h } from 'vue'\r\nimport { ElButton, ElTag, ElImage, ElMessage } from 'element-plus'\r\nimport { DocumentCopy, CopyDocument } from '@element-plus/icons-vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getValueByPath } from '../utils/path'\r\nimport { wrapSFCComponent, createFunctionalRenderer } from '../renderer'\r\nimport EditableInput from './input.vue'\r\nimport EditableNumber from './inputNumber.vue'\r\nimport EditableSelect from './select.vue'\r\n\r\n/**\r\n * 包装 SFC 组件\r\n */\r\nconst input = wrapSFCComponent(EditableInput)\r\nconst inputNumber = wrapSFCComponent(EditableNumber)\r\nconst select = wrapSFCComponent(EditableSelect)\r\n\r\n/**\r\n * button 渲染器\r\n */\r\nconst button = createFunctionalRenderer((props) => {\r\n const rp = props.col.renderProps || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h(ElButton as any, {\r\n type: rp.type || 'primary',\r\n ...rp,\r\n onClick: () => props.onClick?.(props.row, props.col)\r\n }, () => rp.label || val)\r\n})\r\n\r\n/**\r\n * link 渲染器\r\n */\r\nconst link = createFunctionalRenderer((props) => {\r\n const rp = props.col.renderProps || {}\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h('a', {\r\n href: rp.href || '#',\r\n target: rp.blank ? '_blank' : '_self',\r\n style: rp.style || 'color:#409EFF;cursor:pointer;',\r\n }, rp.label || val)\r\n})\r\n\r\n/**\r\n * html 渲染器\r\n */\r\nconst html = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key)\r\n return h('div', {\r\n class: 'line-clamp-2',\r\n innerHTML: val ?? '',\r\n ...(props.col?.renderProps || {})\r\n })\r\n})\r\n\r\n/**\r\n * copy 渲染器\r\n */\r\nconst copy = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps ?? {}\r\n const butStyle = {\r\n 'position': 'absolute',\r\n 'right': '-5px',\r\n 'top': '50%',\r\n 'transform': 'translateY(-50%)',\r\n 'cursor': 'pointer',\r\n 'display': 'none',\r\n 'font-size': '12px',\r\n 'color': rp.iconColor || '#409EFF',\r\n 'user-select': 'none'\r\n }\r\n const testStyle = {\r\n 'padding-right': '10px',\r\n 'display': '-webkit-box',\r\n '-webkit-box-orient': 'vertical',\r\n '-webkit-line-clamp': rp.lineClamp ?? 2,\r\n 'overflow': 'hidden',\r\n ...rp.textStyles\r\n }\r\n return h('div', {\r\n class: 'st_copy_wrapper',\r\n style: 'width: 100%; position: relative; display: inline-block;'\r\n },\r\n [\r\n h('span', {\r\n class: `st_copy_text ${rp.textClass ?? ''}`,\r\n style: testStyle,\r\n title: val\r\n }, val),\r\n val && h('span', {\r\n class: 'st_copy_btn',\r\n style: butStyle,\r\n title: rp.copyTitle || '复制',\r\n onClick: () => {\r\n if (!val) return\r\n try {\r\n if (navigator.clipboard && navigator.clipboard.writeText) {\r\n navigator.clipboard.writeText(val).then(() => {\r\n ElMessage.success(rp.successText ?? '复制成功')\r\n }).catch(() => {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n })\r\n } else {\r\n const textarea = document.createElement('textarea')\r\n textarea.value = val\r\n textarea.style.position = 'fixed'\r\n textarea.style.opacity = '0'\r\n document.body.appendChild(textarea)\r\n textarea.select()\r\n const successful = document.execCommand('copy')\r\n document.body.removeChild(textarea)\r\n\r\n if (successful) {\r\n ElMessage.success(rp.successText ?? '复制成功')\r\n } else {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n }\r\n }\r\n } catch (err) {\r\n ElMessage.error(rp.errorText ?? '复制失败')\r\n }\r\n }\r\n }, [h(DocumentCopy, {\r\n style: 'width: 1em; height: 1em;'\r\n })])\r\n ].filter(Boolean)\r\n )\r\n})\r\n\r\n/**\r\n * img 渲染器\r\n */\r\nconst img = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col?.renderProps || {}\r\n\r\n const getImageList = () => {\r\n if (!val) return []\r\n if (Array.isArray(val)) {\r\n return val.filter(item => item && typeof item === 'string')\r\n }\r\n return [val]\r\n }\r\n\r\n const imageList = getImageList()\r\n\r\n if (imageList.length === 0) {\r\n return rp.placeholder || ''\r\n }\r\n\r\n const defaultStyle = {\r\n width: rp.width || '80px',\r\n height: rp.height || '80px',\r\n marginRight: imageList.length > 1 ? '4px' : '0',\r\n ...(rp.style || {})\r\n }\r\n\r\n if (imageList.length === 1) {\r\n return h(ElImage, {\r\n src: imageList[0],\r\n previewSrcList: rp.previewSrcList || imageList,\r\n fit: rp.fit || 'contain',\r\n style: defaultStyle,\r\n ...rp\r\n })\r\n }\r\n\r\n return h('div',\r\n {\r\n class: 'st_img_wrapper',\r\n style: 'display: flex; align-items: center; position: relative'\r\n },\r\n [\r\n h(ElImage, {\r\n src: imageList[0],\r\n previewSrcList: rp.previewSrcList || imageList,\r\n fit: rp.fit || 'contain',\r\n style: defaultStyle,\r\n ...rp\r\n }),\r\n imageList.length > 1 && h('span', {\r\n class: 'st_img_total',\r\n style: `position: absolute; top: 0; right: 0; `,\r\n title: `${imageList.length}`\r\n }, [h(CopyDocument, { style: `width: 1em; height: 1em; ` })])\r\n ]\r\n )\r\n})\r\n\r\n/**\r\n * dict 渲染器\r\n */\r\nconst dict = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps || {}\r\n const options = rp.options ?? []\r\n const showValue = rp.showValue ?? false\r\n\r\n if (val === null || val === undefined || val === '') return ''\r\n\r\n const values = Array.isArray(val) ? val.map(String) : [String(val)]\r\n const matchedOptions = options.filter((opt: any) => values.includes(String(opt.value)))\r\n const unmatched = values.filter(v => !options.some((opt: any) => String(opt.value) === v))\r\n\r\n const children = matchedOptions.map((item: any, _index: number) => {\r\n return h(\r\n ElTag,\r\n { key: item.value, type: item.listClass, class: item.cssClass, disableTransitions: true },\r\n { default: () => item.label + ' ' }\r\n )\r\n })\r\n\r\n if (showValue && unmatched.length > 0) {\r\n children.push(h('span', {}, unmatched.join(' ')))\r\n }\r\n\r\n return h('div', {}, children)\r\n})\r\n\r\n/**\r\n * map 渲染器\r\n */\r\nconst map = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const options = (props.col.renderProps?.options ?? {}) as Record<string, any>\r\n return val != null ? options[val] ?? '' : ''\r\n})\r\n\r\n/**\r\n * formatter 渲染器\r\n */\r\nexport function isDataColumn(\r\n col: ColumnConfig\r\n): col is any {\r\n return typeof (col as any).formatter === 'function'\r\n}\r\n\r\nconst formatter = createFunctionalRenderer((props) => {\r\n const { col, row } = props\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n if (isDataColumn(col)) {\r\n return col.formatter?.(val, row)\r\n }\r\n return val ?? ''\r\n})\r\n\r\n/**\r\n * icon 渲染器\r\n */\r\nconst icon = createFunctionalRenderer((props) => {\r\n const val = getValueByPath(props.row, props.col.key) ?? ''\r\n const rp = props.col.renderProps || {}\r\n if (!val) return ''\r\n // 判断网络图片\r\n if (/^https?:\\/\\//.test(val)) {\r\n return h(ElImage, {\r\n src: val,\r\n previewSrcList: [val],\r\n fit: 'contain',\r\n style: 'width:40px;height:40px',\r\n ...rp\r\n })\r\n }\r\n // 判断 svg 源码\r\n if (/^\\s*<svg[\\s\\S]*<\\/svg>\\s*$/.test(val)) {\r\n return h('div', {\r\n innerHTML: val,\r\n style: `width:40px;height:40px;display:inline-block;${rp.style || ''}`,\r\n ...rp\r\n })\r\n }\r\n // 默认当作 iconfont\r\n return h('i', {\r\n class: val,\r\n style: `font-size:20px;${rp.style || ''}`,\r\n ...rp\r\n })\r\n})\r\n\r\n/**\r\n * 所有内置渲染器\r\n */\r\nexport const builtInRenderers = {\r\n input,\r\n 'input-number': inputNumber,\r\n select,\r\n button,\r\n link,\r\n html,\r\n copy,\r\n img,\r\n dict,\r\n map,\r\n formatter,\r\n icon,\r\n}\r\n\r\n/**\r\n * 安装所有内置渲染器\r\n */\r\nexport function registerBuiltInRenderers(registry: { registerMultiple: (renderers: Record<string, any>) => void }) {\r\n registry.registerMultiple(builtInRenderers)\r\n}\r\n\r\n/**\r\n * 创建默认渲染器集合(兼容旧 API)\r\n * @deprecated 建议使用插件化架构\r\n */\r\nexport function createRenderer() {\r\n return builtInRenderers\r\n}\r\n","import { computed } from 'vue'\r\n\r\nimport { ButtonConfig } from \"../types\"\r\n/**\r\n * useOperationColumn\r\n *\r\n * 操作列专用逻辑 Hook,负责:\r\n * 1. 根据权限判断操作列是否需要显示\r\n * 2. 计算操作列宽度(支持按钮自定义宽度)\r\n * 3. 支持行级 visible 配置\r\n * @param buttonConfigs 操作列按钮配置\r\n * @param maxbtn 操作列最多显示按钮数量(超过的不参与宽度计算)\r\n * @param userPermissions 当前用户权限列表\r\n */\r\nexport function useOperationColumn(\r\n buttonConfigs: ButtonConfig[],\r\n maxbtn = 10,\r\n userPermissions: string[] = []\r\n) {\r\n /** 默认按钮宽度 */\r\n const defaultWidth = 60\r\n\r\n /** 超级权限标识 */\r\n const all_permission = '*:*:*'\r\n\r\n /** --------------------------\r\n * 权限判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断是否具备按钮权限\r\n *\r\n * 规则:\r\n * - permission 未配置 ⇒ 永远有权限\r\n * - permission 为 string | string[] ⇒ 与用户权限匹配\r\n */\r\n const hasPermi = (value?: string | string[]) => {\r\n if (!value) return true\r\n\r\n const permArray = Array.isArray(value) ? value : [value]\r\n return userPermissions.some(\r\n p => p === all_permission || permArray.includes(p)\r\n )\r\n }\r\n\r\n /** --------------------------\r\n * 仅基于权限(不考虑行级 visible)\r\n * 适用于:表格未加载数据时的判断\r\n * -------------------------- */\r\n\r\n /**\r\n * 是否至少存在一个有权限的按钮\r\n * 用于判断操作列是否需要渲染\r\n */\r\n const hasAnyButton = computed(() => {\r\n return buttonConfigs.some(btn => hasPermi(btn.permission))\r\n })\r\n\r\n /**\r\n * 操作列宽度(仅基于权限)\r\n * 用于无行数据时的兜底宽度计算\r\n */\r\n const optWidth = computed(() => {\r\n const permittedBtns = buttonConfigs\r\n .filter(btn => hasPermi(btn.permission))\r\n .slice(0, maxbtn)\r\n\r\n return permittedBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n })\r\n\r\n /** --------------------------\r\n * 权限 + 行级 visible\r\n * -------------------------- */\r\n\r\n /**\r\n * 判断某个按钮在某一行是否可见\r\n */\r\n const isButtonVisible = (btn: ButtonConfig, row: any) => {\r\n return (\r\n hasPermi(btn.permission) &&\r\n (btn.visible ? btn.visible(row) : true)\r\n )\r\n }\r\n\r\n /**\r\n * 单行操作列宽度\r\n */\r\n const optRowWidth = (row: any) => {\r\n const visibleBtns = buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n\r\n return visibleBtns.reduce(\r\n (sum, btn) => sum + (btn.width ?? defaultWidth),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 遍历所有行,获取最大操作列宽度\r\n */\r\n const getMaxOptWidth = (rows: any[]) => {\r\n if (!rows?.length) return optWidth.value\r\n return rows.reduce(\r\n (max, row) => Math.max(max, optRowWidth(row)),\r\n 0\r\n )\r\n }\r\n\r\n /**\r\n * 判断是否至少有一行存在可见按钮\r\n */\r\n const hasAnyVisibleButton = (rows: any[]) => {\r\n if (!rows?.length) return false\r\n return rows.some(row =>\r\n buttonConfigs.some(btn => isButtonVisible(btn, row))\r\n )\r\n }\r\n\r\n const getVisibleButtons = (row: any) => {\r\n return buttonConfigs\r\n .filter(btn => isButtonVisible(btn, row))\r\n .slice(0, maxbtn)\r\n }\r\n\r\n return {\r\n hasAnyButton,\r\n optWidth,\r\n hasAnyVisibleButton,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n }\r\n}\r\n","<template>\r\n <!-- ========== selection 列 ========== -->\r\n <el-table-column\r\n v-if=\"col.type === 'selection'\"\r\n type=\"selection\"\r\n v-bind=\"col.columnProps\"\r\n />\r\n\r\n <!-- ========== index 列 ========== -->\r\n <el-table-column\r\n v-else-if=\"col.type === 'index'\"\r\n type=\"index\"\r\n :label=\"col.label || '#'\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps\"\r\n >\r\n <template #default=\"{ $index }\">\r\n {{ computeIndex($index) }}\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== operation 列 ========== -->\r\n <el-table-column\r\n v-else-if=\"col.type === 'operation' && showOperationColumn\"\r\n :label=\"col.label || '操作'\"\r\n align=\"center\"\r\n v-bind=\"{\r\n ...col.columnProps,\r\n width: operationWidth\r\n }\"\r\n >\r\n <template #default=\"{ row }\">\r\n <el-button\r\n v-for=\"btn in getVisibleButtons(row)\"\r\n :key=\"btn.label\"\r\n :type=\"btn.type || 'primary'\"\r\n link\r\n @click=\"btn.action(row)\"\r\n >\r\n {{ btn.label }}\r\n </el-button>\r\n </template>\r\n </el-table-column>\r\n\r\n <!-- ========== 普通列 / renderer / editable ========== -->\r\n <el-table-column\r\n v-else-if=\"isDataOrOperationColumn(col)\"\r\n :label=\"col.label\"\r\n align=\"center\"\r\n v-bind=\"col.columnProps || {}\"\r\n >\r\n \r\n <template #default=\"scope\">\r\n <!-- 父组件插槽优先 -->\r\n <template v-if=\"col.render === 'slot' && $slots[col?.slot || col.key]\">\r\n <slot :name=\"col?.slot || col.key\" v-bind=\"scope\" />\r\n </template>\r\n\r\n <!-- renderer -->\r\n <component\r\n v-else-if=\"col.render && renderer[col.render]\"\r\n :is=\"renderer[col.render]\"\r\n :row=\"scope.row\"\r\n :col=\"col\"\r\n :onCellChange=\"handleCellChange\"\r\n :onCellBlur=\"handleCellBlur\"\r\n :onCellEnter=\"handleCellEnter\"\r\n :onClick=\"handleCellClick\"\r\n />\r\n <!-- 默认文本 -->\r\n <span v-else\r\n :style=\"col.renderProps?.style || ''\"\r\n :class=\"col.renderProps?.class || ''\"\r\n :title=\"getValueByPath(scope.row, col.key)\">\r\n {{ getValueByPath(scope.row, col.key) }}\r\n </span>\r\n </template>\r\n </el-table-column>\r\n \r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { computed, toRefs } from 'vue'\r\nimport type { PropType } from 'vue'\r\nimport type { ColumnConfig } from '../types'\r\nimport { getRendererManager } from '../renderer'\r\nimport { registerBuiltInRenderers } from '../renderers'\r\nimport { useOperationColumn } from '../hooks/useOperationColumn'\r\nimport { getValueByPath } from '../utils/path'\r\n\r\nconst props = defineProps({\r\n col: { type: Object as PropType<ColumnConfig>, required: true },\r\n permissions: { type: Array as PropType<string[]>, default: () => [] },\r\n pagination: { type: Object, default: () => ({}) },\r\n})\r\n\r\nconst emit = defineEmits(['cellBlur', 'cellEnter', 'cellChange', 'cellClick'])\r\n\r\nconst computeIndex = (index: number) => {\r\n const page = props.pagination?.page\r\n const size = props.pagination?.size\r\n return page && size ? (page - 1) * size + index + 1 : index + 1\r\n}\r\n\r\n/** 解构 col 响应式引用 */\r\nconst { col } = toRefs(props)\r\n\r\n/** ========== 事件统一上抛 ========== */\r\nconst handleCellChange = (row: any, key: string) => emit('cellChange', row, key)\r\nconst handleCellBlur = (row: any, key: string) => emit('cellBlur', row, key)\r\nconst handleCellEnter = (row: any, key: string) => emit('cellEnter', row, key)\r\nconst handleCellClick = (row: any, col: any) => emit('cellClick', row, col)\r\n\r\n/** ========== renderer 注册 ========== */\r\n// 注册内置渲染器(重复调用会自动跳过已存在的)\r\nregisterBuiltInRenderers(getRendererManager())\r\n\r\n// 获取所有渲染器(内置 + 自定义)\r\nconst renderer = computed(() => {\r\n const manager = getRendererManager()\r\n const allRenderers: Record<string, any> = {}\r\n\r\n // 合并内置渲染器和自定义渲染器\r\n manager.names().forEach((name: string) => {\r\n const r = manager.get(name)\r\n if (r) allRenderers[name] = r\r\n })\r\n\r\n return allRenderers\r\n})\r\n\r\n/** ========== operation 列逻辑 ========== */\r\nconst {\r\n hasAnyButton,\r\n hasAnyVisibleButton,\r\n optWidth,\r\n getMaxOptWidth,\r\n getVisibleButtons\r\n} = useOperationColumn(\r\n col.value.buttons || [],\r\n col.value.maxbtn ?? 10,\r\n props.permissions || []\r\n)\r\n\r\n/** 是否显示操作列 */\r\nconst showOperationColumn = computed(() => {\r\n const buttons = col.value.buttons || []\r\n if (!buttons.length) return false // 没有配置按钮直接隐藏\r\n const rows = col.value.__rows || []\r\n // 无行数据时,至少有一个按钮有权限就显示\r\n if (!rows.length) return hasAnyButton.value\r\n // 有行数据时,至少一行有可见按钮才显示\r\n return hasAnyVisibleButton(col.value.__rows || [])\r\n})\r\n\r\n/** 操作列宽度 */\r\nconst operationWidth = computed(() => {\r\n // 无行数据,用静态宽度\r\n if (!col.value.__rows) return optWidth.value\r\n // 有行数据,取最大宽度\r\n return getMaxOptWidth(col.value.__rows)\r\n})\r\n\r\nfunction isDataOrOperationColumn(c: ColumnConfig) {\r\n if (c.type === 'selection' || c.type === 'index') return false\r\n if (c.type === 'operation' && !showOperationColumn.value) return false\r\n if (c.visible === false) return false\r\n return true\r\n}\r\n</script>","import { ref, watch } from 'vue'\r\n\r\n\r\n/**\r\n * 合并默认列配置和缓存配置\r\n *\r\n * 设计原则:\r\n * 1️⃣ 列顺序:以 defaultColumns 为准\r\n * 2️⃣ 列增减:以 defaultColumns 为准\r\n * 3️⃣ 缓存只覆盖用户可配置字段(如 visible)\r\n */\r\nfunction mergeColumns(\r\n defaultColumns: any[],\r\n cacheColumns: Array<{ key: string; visible?: boolean }>\r\n) {\r\n if (!cacheColumns?.length) return defaultColumns\r\n\r\n // 建立 key => cache 映射表,提升查找效率\r\n const cacheMap = new Map(\r\n cacheColumns.map(c => [c.key, c])\r\n )\r\n\r\n return defaultColumns.map(col => {\r\n const cacheCol = cacheMap.get(col.key)\r\n\r\n // 只允许缓存覆盖「可配置字段」\r\n if (!cacheCol) return col\r\n\r\n return {\r\n ...col,\r\n visible:\r\n typeof cacheCol.visible === 'boolean'\r\n ? cacheCol.visible\r\n : col.visible\r\n }\r\n })\r\n}\r\n\r\n\r\n/**\r\n * useTableColumns\r\n *\r\n * 表格列管理 Hook\r\n *\r\n * 职责:\r\n * - 管理表格列顺序\r\n * - 管理列显示 / 隐藏\r\n * - 持久化用户配置\r\n */\r\nexport function useTableColumns(\r\n defaultColumns: any[],\r\n options?: {\r\n /** 缓存唯一标识 */\r\n cacheKey?: string\r\n /** 存储介质,默认 localStorage */\r\n storage?: Storage\r\n }\r\n) {\r\n\r\n /** 解构参数并设置默认值 */\r\n const { cacheKey, storage = localStorage } = options || {}\r\n\r\n /**\r\n * 如果没有 cacheKey,则不启用缓存\r\n * (例如公共页面、未登录页面)\r\n * 从缓存中读取列配置\r\n */\r\n const cache = cacheKey ? storage.getItem(cacheKey) : null\r\n\r\n /**\r\n * 响应式列配置\r\n * 初始化时合并默认列和缓存列\r\n */\r\n const columns = ref(\r\n mergeColumns(\r\n defaultColumns,\r\n cache ? JSON.parse(cache) : []\r\n )\r\n )\r\n\r\n /**\r\n * 监听列变化,自动写入缓存\r\n */\r\n watch(\r\n columns,\r\n (newVal: any) => {\r\n if (!cacheKey) return\r\n\r\n /**\r\n * ⚠️ 只保存“轻量配置”\r\n * 避免把 render / action / 函数序列化进 localStorage\r\n */\r\n const lightColumns = newVal.map((col: any) => ({\r\n key: col.key,\r\n visible: col.visible,\r\n columnOpts: col.columnOpts\r\n }))\r\n\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(lightColumns)\r\n )\r\n },\r\n { deep: true }\r\n )\r\n\r\n /**\r\n * 对外暴露的 API\r\n */\r\n return {\r\n /** 当前列配置(响应式) */\r\n columns,\r\n\r\n /**\r\n * 主动设置列配置\r\n * 常用于:列设置弹窗 / 拖拽排序完成\r\n */\r\n setColumns(newColumns: any[]) {\r\n columns.value = mergeColumns(\r\n defaultColumns,\r\n newColumns\r\n )\r\n\r\n if (cacheKey) {\r\n storage.setItem(\r\n cacheKey,\r\n JSON.stringify(newColumns)\r\n )\r\n }\r\n },\r\n\r\n /**\r\n * 重置为默认列配置\r\n */\r\n resetColumns() {\r\n columns.value = defaultColumns\r\n\r\n if (cacheKey) {\r\n storage.removeItem(cacheKey)\r\n }\r\n }\r\n }\r\n}\r\n","<template>\r\n <el-table ref=\"tableRef\"\r\n v-bind=\"$attrs\"\r\n :data=\"data\"\r\n :row-key=\"rowKey\"\r\n class=\"smart_table\"\r\n v-loading=\"loading\">\r\n <TableColumn \r\n v-for=\"col in cachedColumns\" \r\n :key=\"col.key\" \r\n :col=\"col\" \r\n :permissions=\"permissions\"\r\n :pagination=\"pagination\"\r\n @cell-change=\"handleCellChange\"\r\n @cell-blur=\"handleCellBlur\"\r\n @cell-enter=\"handleCellEnter\"\r\n @cell-click=\"handleCellClick\">\r\n <template v-for=\"col in cachedColumns\" #[col.key]=\"slotProps\">\r\n <slot :name=\"col.key\" v-bind=\"slotProps\" />\r\n </template>\r\n </TableColumn>\r\n </el-table>\r\n</template>\r\n\r\n<script setup lang=\"ts\" name=\"SmartTable\">\r\n import { PropType, ref, watch } from 'vue'\r\n import TableColumn from './column/index.vue'\r\n import type { BaseColumn, ColumnConfig } from './types'\r\n import { useTableColumns } from \"./hooks/useTableColumns\"\r\n\r\n const props = defineProps({\r\n data: { type: Array, default: () => [] },\r\n columns: { type: Array, default: () => [] },\r\n rowKey: { type: String, default: 'id' },\r\n loading: { type: Boolean, default: false },\r\n permissions: {\r\n type: Array as PropType<string[]>,\r\n default: () => []\r\n },\r\n cacheKey: String,\r\n pagination: { type: Object, default: () => ({}) },\r\n\r\n })\r\n \r\n const emit = defineEmits([\r\n 'update:columns',\r\n 'cellChange',\r\n 'cellBlur',\r\n 'cellEnter',\r\n 'cell-click',\r\n ])\r\n\r\n // ------------------ columns 处理 ------------------\r\n const { columns: cachedColumns } = useTableColumns(props.columns, {\r\n cacheKey: props.cacheKey ?? '',\r\n })\r\n watch(\r\n cachedColumns,\r\n (val: ColumnConfig[]) => emit(\"update:columns\", val),\r\n { deep: true, immediate: true },\r\n )\r\n\r\n // ----------------事件封装 ------------------\r\n const handleCellChange = (row: any, key: string) => emit('cellChange', row, key)\r\n const handleCellBlur = (row: any, key: string) => {\r\n emit('cellBlur', row, key)\r\n }\r\n const handleCellEnter = (row: any, key: string) => {\r\n console.log('enter')\r\n emit('cellEnter', row, key)\r\n }\r\n \r\n // SmartTable\r\n const handleCellClick = (row: any, col: any) => {\r\n if(!col) return\r\n emit('cell-click', row, col)\r\n }\r\n\r\n // el-table\r\n const tableRef = ref();\r\n defineExpose({\r\n tableRef,\r\n });\r\n\r\n</script>\r\n\r\n<style>\r\n .smart_table {\r\n width: 100%;\r\n }\r\n \r\n .st_copy_wrapper:hover .st_copy_btn {\r\n display: inline-block !important;\r\n }\r\n\r\n .st_copy_btn:hover {\r\n transform: translateY(-50%) scale(1.1);\r\n }\r\n</style>\r\n","/**\r\n * 全局配置管理\r\n */\r\nimport type { SmartTableConfig } from './types'\r\nimport { getRendererManager } from './renderer'\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst defaultConfig: SmartTableConfig = {\r\n defaultPagination: {\r\n page: 1,\r\n size: 10,\r\n total: 0\r\n },\r\n defaultTableProps: {},\r\n defaultColumnProps: {}\r\n}\r\n\r\n/**\r\n * 全局配置类\r\n */\r\nclass ConfigManager {\r\n private config: SmartTableConfig = { ...defaultConfig }\r\n\r\n /**\r\n * 获取所有配置\r\n */\r\n getConfig(): SmartTableConfig {\r\n return { ...this.config }\r\n }\r\n\r\n /**\r\n * 设置配置\r\n */\r\n setConfig(config: Partial<SmartTableConfig>): void {\r\n this.config = this.mergeConfig(this.config, config)\r\n\r\n // 如果有自定义渲染器,自动注册\r\n if (config.renderers) {\r\n const manager = getRendererManager()\r\n manager.registerMultiple(config.renderers)\r\n }\r\n }\r\n\r\n /**\r\n * 获取特定配置项\r\n */\r\n get<K extends keyof SmartTableConfig>(key: K): SmartTableConfig[K] {\r\n return this.config[key]\r\n }\r\n\r\n /**\r\n * 重置为默认配置\r\n */\r\n reset(): void {\r\n this.config = { ...defaultConfig }\r\n }\r\n\r\n /**\r\n * 深度合并配置\r\n */\r\n private mergeConfig(target: any, source: any): any {\r\n const result = { ...target }\r\n\r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n result[key] = this.mergeConfig(target[key] || {}, source[key])\r\n } else {\r\n result[key] = source[key]\r\n }\r\n }\r\n\r\n return result\r\n }\r\n}\r\n\r\n/**\r\n * 全局配置管理器单例\r\n */\r\nlet globalConfigManager: ConfigManager | null = null\r\n\r\n/**\r\n * 获取全局配置管理器\r\n */\r\nexport function getConfigManager(): ConfigManager {\r\n if (!globalConfigManager) {\r\n globalConfigManager = new ConfigManager()\r\n }\r\n return globalConfigManager\r\n}\r\n\r\n/**\r\n * 安装插件(用于 Vue.use())\r\n */\r\nexport interface SmartTablePlugin {\r\n install: (options?: SmartTableConfig) => void\r\n}\r\n\r\n/**\r\n * 创建插件实例\r\n */\r\nexport function createSmartTablePlugin(defaultOptions?: SmartTableConfig): SmartTablePlugin {\r\n return {\r\n install(options?: SmartTableConfig) {\r\n const manager = getConfigManager()\r\n const config = { ...defaultOptions, ...options }\r\n if (config) {\r\n manager.setConfig(config)\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 全局配置快捷方法\r\n */\r\nexport function setSmartTableConfig(config: Partial<SmartTableConfig>): void {\r\n getConfigManager().setConfig(config)\r\n}\r\n\r\nexport function getSmartTableConfig(): SmartTableConfig {\r\n return getConfigManager().getConfig()\r\n}\r\n","/**\r\n * 增强类型系统 - 提供更好的类型推断\r\n */\r\nimport type { ColumnConfig, RendererName } from '../components/SmartTable/types'\r\n\r\n/**\r\n * 提取行数据的类型\r\n */\r\nexport type ExtractRowType<T> = T extends ColumnConfig<infer R> ? R : never\r\n\r\n/**\r\n * 根据列配置提取表格数据类型\r\n */\r\nexport type TableDataFromColumns<T extends ColumnConfig[]> = T extends (infer C)[]\r\n ? C extends ColumnConfig<infer R>\r\n ? R\r\n : any\r\n : any\r\n\r\n/**\r\n * 渲染器 Props 类型推断\r\n */\r\nexport type InferRendererProps<T extends RendererName> =\r\n T extends 'html'\r\n ? { style?: string; class?: string; [key: string]: any }\r\n : T extends 'copy'\r\n ? { successText?: string; errorText?: string; iconColor?: string; [key: string]: any }\r\n : T extends 'img'\r\n ? { width?: string | number; height?: string | number; fit?: string; previewSrcList?: string[]; [key: string]: any }\r\n : T extends 'dict'\r\n ? { options: Array<{ label: string; value: string | number; listClass?: string; cssClass?: string }>; showValue?: boolean }\r\n : T extends 'map'\r\n ? { options: Record<string | number, any> }\r\n : T extends 'input'\r\n ? { placeholder?: string; size?: 'small' | 'default' | 'large'; clearable?: boolean }\r\n : T extends 'select'\r\n ? { options: Array<{ label: string; value: string | number }>; placeholder?: string; clearable?: boolean }\r\n : { [key: string]: any }\r\n\r\n/**\r\n * 快捷创建列的辅助函数(类型安全简化版)\r\n */\r\nexport function defineColumn(\r\n key: string,\r\n config?: Partial<Omit<ColumnConfig, 'key'>>\r\n): ColumnConfig {\r\n return {\r\n key,\r\n ...config\r\n } as ColumnConfig\r\n}\r\n"],"names":["RendererManager","__publicField","name","renderer","renderers","globalRendererManager","getRendererManager","wrapSFCComponent","comp","defineComponent","props","h","createFunctionalRenderer","render","validateRendererProps","rendererName","renderProps","getValueByPath","obj","path","acc","key","setValueByPath","value","keys","lastKey","target","__props","ref","watch","v","onBlur","_a","onEnter","_openBlock","_createBlock","_component_el_input","_mergeProps","$event","_component_el_input_number","onChange","_component_el_select","_createElementBlock","_Fragment","opt","_component_el_option","input","EditableInput","inputNumber","EditableNumber","select","EditableSelect","button","rp","val","ElButton","link","html","copy","butStyle","testStyle","ElMessage","textarea","successful","DocumentCopy","img","imageList","item","defaultStyle","ElImage","CopyDocument","dict","options","showValue","values","matchedOptions","unmatched","children","_index","ElTag","map","isDataColumn","col","formatter","row","icon","builtInRenderers","registerBuiltInRenderers","registry","createRenderer","useOperationColumn","buttonConfigs","maxbtn","userPermissions","all_permission","hasPermi","permArray","hasAnyButton","computed","btn","optWidth","sum","isButtonVisible","optRowWidth","rows","max","emit","__emit","computeIndex","index","page","size","_b","toRefs","handleCellChange","handleCellBlur","handleCellEnter","handleCellClick","manager","allRenderers","r","hasAnyVisibleButton","getMaxOptWidth","getVisibleButtons","showOperationColumn","operationWidth","isDataOrOperationColumn","c","_unref","_component_el_table_column","_withCtx","$index","_createTextVNode","_toDisplayString","_renderList","_component_el_button","scope","$slots","_renderSlot","_ctx","_normalizeProps","_resolveDynamicComponent","_normalizeStyle","_normalizeClass","_hoisted_1","mergeColumns","defaultColumns","cacheColumns","cacheMap","cacheCol","useTableColumns","cacheKey","storage","cache","columns","newVal","lightColumns","newColumns","cachedColumns","tableRef","__expose","_withDirectives","_component_el_table","$attrs","TableColumn","slotProps","defaultConfig","ConfigManager","config","source","result","globalConfigManager","getConfigManager","setSmartTableConfig","getSmartTableConfig","defineColumn"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(function(c,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("element-plus"),require("@element-plus/icons-vue")):typeof define=="function"&&define.amd?define(["exports","vue","element-plus","@element-plus/icons-vue"],t):(c=typeof globalThis<"u"?globalThis:c||self,t(c.Vue3SmartTable={},c.Vue,c.ElementPlus,c.ElementPlusIconsVue))})(this,(function(c,t,
|
|
2
|
-
/*$vite$:1*/`,document.head.appendChild(D);class U{constructor(){L(this,"renderers",new Map)}register(e,r){this.renderers.has(e)&&process.env.NODE_ENV==="development"&&console.debug(`[SmartTable] Renderer "${e}" already registered, skipping.`),this.renderers.set(e,r)}registerMultiple(e){Object.entries(e).forEach(([r,i])=>{this.renderers.has(r)||this.renderers.set(r,i)})}get(e){return this.renderers.get(e)}has(e){return this.renderers.has(e)}unregister(e){return this.renderers.delete(e)}clear(){this.renderers.clear()}names(){return Array.from(this.renderers.keys())}}let A=null;function V(){return A||(A=new U),A}function M(n){return t.defineComponent({props:["row","col","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>t.h(n,e)}})}function B(n){return t.defineComponent({props:["row","col","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>n(e)}})}function H(n,e){if(process.env.NODE_ENV!=="production"&&e)switch(n){case"dict":(!e.options||!Array.isArray(e.options))&&console.warn("[SmartTable] 'dict' renderer requires 'options' array, received:",e.options);break;case"select":!e.options||!Array.isArray(e.options)?console.warn("[SmartTable] 'select' renderer requires 'options' array, received:",e.options):e.options.length===0&&console.warn("[SmartTable] 'select' renderer 'options' array is empty");break;case"map":(!e.options||typeof e.options!="object")&&console.warn("[SmartTable] 'map' renderer requires 'options' object, received:",e.options);break;case"link":(!e.href||typeof e.href!="string")&&console.warn("[SmartTable] 'link' renderer requires 'href' string, received:",e.href);break;case"input-number":e.min!==void 0&&e.max!==void 0&&e.min>e.max&&console.warn(`[SmartTable] 'input-number' renderer: min (${e.min}) should not be greater than max (${e.max})`);break}}function k(n,e){if(!(!n||!e))return e.split(".").reduce((r,i)=>r==null?void 0:r[i],n)}function R(n,e,r){if(!n||!e)return;const i=e.split("."),o=i.pop(),l=i.reduce((s,u)=>(s[u]||(s[u]={}),s[u]),n);l[o]=r}const Y=t.defineComponent({__name:"input",props:{row:{},col:{},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,l=>{R(e.row,e.col.key,l)});const i=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},o=()=>{var l;return(l=e.onCellEnter)==null?void 0:l.call(e,e.row,e.col)};return(l,s)=>{const u=t.resolveComponent("el-input");return t.openBlock(),t.createBlock(u,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":s[0]||(s[0]=f=>r.value=f)},{placeholder:"",size:"small",clearable:!0,...n.col.renderProps},{onBlur:i,onKeyup:t.withKeys(o,["enter"])}),null,16,["modelValue"])}}}),G=t.defineComponent({__name:"inputNumber",props:{row:{},col:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,l=>{var s;R(e.row,e.col.key,l),(s=e.onCellChange)==null||s.call(e,e.row,e.col)});const i=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},o=()=>{var l;return(l=e.onCellEnter)==null?void 0:l.call(e,e.row,e.col)};return(l,s)=>{const u=t.resolveComponent("el-input-number");return t.openBlock(),t.createBlock(u,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":s[0]||(s[0]=f=>r.value=f)},{min:0,max:99999,controls:!1,size:"small",...n.col.renderProps},{onBlur:i,onKeyup:t.withKeys(o,["enter"])}),null,16,["modelValue"])}}}),Q=t.defineComponent({__name:"select",props:{row:{},col:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,s=>{R(e.row,e.col.key,s)});const i=()=>{var s;return(s=e.onCellChange)==null?void 0:s.call(e,e.row,e.col)},o=()=>{var s;return(s=e.onCellBlur)==null?void 0:s.call(e,e.row,e.col)},l=()=>{var s;return(s=e.onCellEnter)==null?void 0:s.call(e,e.row,e.col)};return(s,u)=>{const f=t.resolveComponent("el-option"),g=t.resolveComponent("el-select");return t.openBlock(),t.createBlock(g,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":u[0]||(u[0]=b=>r.value=b)},{placeholder:"请选择",size:"small",clearable:!0,...n.col.renderProps},{onChange:i,onBlur:o,onKeyup:t.withKeys(l,["enter"])}),{default:t.withCtx(()=>{var b;return[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(((b=n.col.renderProps)==null?void 0:b.options)||[],m=>(t.openBlock(),t.createBlock(f,{key:m.value,label:m.label,value:m.value},null,8,["label","value"]))),128))]}),_:1},16,["modelValue"])}}}),X=M(Y),Z=M(G),v=M(Q),ee=B(n=>{const e=n.col.renderProps||{},r=k(n.row,n.col.key);return t.h(h.ElButton,{type:e.type||"primary",...e,onClick:()=>{var i;return(i=n.onClick)==null?void 0:i.call(n,n.row,n.col)}},()=>e.label||r)}),te=B(n=>{const e=n.col.renderProps||{},r=k(n.row,n.col.key);return t.h("a",{href:e.href||"#",target:e.blank?"_blank":"_self",style:e.style||"color:#409EFF;cursor:pointer;"},e.label||r)}),ne=B(n=>{var r;const e=k(n.row,n.col.key);return t.h("div",{class:"line-clamp-2",innerHTML:e??"",...((r=n.col)==null?void 0:r.renderProps)||{}})}),re=B(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps??{},i={position:"absolute",right:"-5px",top:"50%",transform:"translateY(-50%)",cursor:"pointer",display:"none","font-size":"12px",color:r.iconColor||"#409EFF","user-select":"none"};return t.h("div",{class:"st_copy_wrapper",style:"width: 100%; position: relative; display: inline-block;"},[t.h("span",{class:"st_copy_text line-clamp-1",style:"padding-right: 10px; display: block;"},e),e&&t.h("span",{class:"st_copy_btn",style:i,title:r.copyTitle||"复制",onClick:()=>{if(e)try{if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(e).then(()=>{h.ElMessage.success(r.successText??"复制成功")}).catch(()=>{h.ElMessage.error(r.errorText??"复制失败")});else{const o=document.createElement("textarea");o.value=e,o.style.position="fixed",o.style.opacity="0",document.body.appendChild(o),o.select();const l=document.execCommand("copy");document.body.removeChild(o),l?h.ElMessage.success(r.successText??"复制成功"):h.ElMessage.error(r.errorText??"复制失败")}}catch{h.ElMessage.error(r.errorText??"复制失败")}}},[t.h(K.DocumentCopy,{style:"width: 1em; height: 1em;"})])].filter(Boolean))}),le=B(n=>{var s;const e=k(n.row,n.col.key)??"",r=((s=n.col)==null?void 0:s.renderProps)||{},o=e?Array.isArray(e)?e.filter(u=>u&&typeof u=="string"):[e]:[];if(o.length===0)return r.placeholder||"";const l={width:r.width||"80px",height:r.height||"80px",marginRight:o.length>1?"4px":"0",...r.style||{}};return o.length===1?t.h(h.ElImage,{src:o[0],previewSrcList:r.previewSrcList||o,fit:r.fit||"contain",style:l,...r}):t.h("div",{class:"st_img_wrapper",style:"display: flex; align-items: center; position: relative"},[t.h(h.ElImage,{src:o[0],previewSrcList:r.previewSrcList||o,fit:r.fit||"contain",style:l,...r}),o.length>1&&t.h("span",{class:"st_img_total",style:"position: absolute; top: 0; right: 0; ",title:`${o.length}`},[t.h(K.CopyDocument,{style:"width: 1em; height: 1em; "})])])}),oe=B(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps||{},i=r.options??[],o=r.showValue??!1;if(e==null||e==="")return"";const l=Array.isArray(e)?e.map(String):[String(e)],s=i.filter(g=>l.includes(String(g.value))),u=l.filter(g=>!i.some(b=>String(b.value)===g)),f=s.map((g,b)=>t.h(h.ElTag,{key:g.value,type:g.listClass,class:g.cssClass,disableTransitions:!0},{default:()=>g.label+" "}));return o&&u.length>0&&f.push(t.h("span",{},u.join(" "))),t.h("div",{},f)}),ie=B(n=>{var i;const e=k(n.row,n.col.key)??"",r=((i=n.col.renderProps)==null?void 0:i.options)??{};return e!=null?r[e]??"":""});function se(n){return typeof n.formatter=="function"}const ae=B(n=>{var o;const{col:e,row:r}=n,i=k(n.row,n.col.key)??"";return se(e)?(o=e.formatter)==null?void 0:o.call(e,i,r):i??""}),ce=B(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps||{};return e?/^https?:\/\//.test(e)?t.h(h.ElImage,{src:e,previewSrcList:[e],fit:"contain",style:"width:40px;height:40px",...r}):/^\s*<svg[\s\S]*<\/svg>\s*$/.test(e)?t.h("div",{innerHTML:e,style:`width:40px;height:40px;display:inline-block;${r.style||""}`,...r}):t.h("i",{class:e,style:`font-size:20px;${r.style||""}`,...r}):""}),O={input:X,"input-number":Z,select:v,button:ee,link:te,html:ne,copy:re,img:le,dict:oe,map:ie,formatter:ae,icon:ce};function N(n){n.registerMultiple(O)}function ue(){return O}function de(n,e=10,r=[]){const o="*:*:*",l=a=>{if(!a)return!0;const p=Array.isArray(a)?a:[a];return r.some(y=>y===o||p.includes(y))},s=t.computed(()=>n.some(a=>l(a.permission))),u=t.computed(()=>n.filter(p=>l(p.permission)).slice(0,e).reduce((p,y)=>p+(y.width??60),0)),f=(a,p)=>l(a.permission)&&(a.visible?a.visible(p):!0),g=a=>n.filter(y=>f(y,a)).slice(0,e).reduce((y,S)=>y+(S.width??60),0);return{hasAnyButton:s,optWidth:u,hasAnyVisibleButton:a=>a!=null&&a.length?a.some(p=>n.some(y=>f(y,p))):!1,getMaxOptWidth:a=>a!=null&&a.length?a.reduce((p,y)=>Math.max(p,g(y)),0):u.value,getVisibleButtons:a=>n.filter(p=>f(p,a)).slice(0,e)}}const fe=["title"],me=t.defineComponent({__name:"index",props:{col:{type:Object,required:!0},permissions:{type:Array,default:()=>[]},pagination:{type:Object,default:()=>({})}},emits:["cellBlur","cellEnter","cellChange","cellClick"],setup(n,{emit:e}){const r=n,i=e,o=d=>{var x,_;const C=(x=r.pagination)==null?void 0:x.page,E=(_=r.pagination)==null?void 0:_.size;return C&&E?(C-1)*E+d+1:d+1},{col:l}=t.toRefs(r),s=(d,C)=>i("cellChange",d,C),u=(d,C)=>i("cellBlur",d,C),f=(d,C)=>i("cellEnter",d,C),g=(d,C)=>i("cellClick",d,C);N(V());const b=t.computed(()=>{const d=V(),C={};return d.names().forEach(E=>{const x=d.get(E);x&&(C[E]=x)}),C}),{hasAnyButton:m,hasAnyVisibleButton:w,optWidth:a,getMaxOptWidth:p,getVisibleButtons:y}=de(l.value.buttons||[],l.value.maxbtn??10,r.permissions||[]),S=t.computed(()=>(l.value.buttons||[]).length?(l.value.__rows||[]).length?w(l.value.__rows||[]):m.value:!1),$=t.computed(()=>l.value.__rows?p(l.value.__rows):a.value);function ke(d){return!(d.type==="selection"||d.type==="index"||d.type==="operation"&&!S.value||d.visible===!1)}return(d,C)=>{const E=t.resolveComponent("el-table-column"),x=t.resolveComponent("el-button");return t.unref(l).type==="selection"?(t.openBlock(),t.createBlock(E,t.mergeProps({key:0,type:"selection"},t.unref(l).columnProps),null,16)):t.unref(l).type==="index"?(t.openBlock(),t.createBlock(E,t.mergeProps({key:1,type:"index",label:t.unref(l).label||"#",align:"center"},t.unref(l).columnProps),{default:t.withCtx(({$index:_})=>[t.createTextVNode(t.toDisplayString(o(_)),1)]),_:1},16,["label"])):t.unref(l).type==="operation"&&S.value?(t.openBlock(),t.createBlock(E,t.mergeProps({key:2,label:t.unref(l).label||"操作",align:"center"},{...t.unref(l).columnProps,width:$.value}),{default:t.withCtx(({row:_})=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(t.unref(y)(_),T=>(t.openBlock(),t.createBlock(x,{key:T.label,type:T.type||"primary",link:"",onClick:I=>T.action(_)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(T.label),1)]),_:2},1032,["type","onClick"]))),128))]),_:1},16,["label"])):ke(t.unref(l))?(t.openBlock(),t.createBlock(E,t.mergeProps({key:3,label:t.unref(l).label,align:"center"},t.unref(l).columnProps||{}),{default:t.withCtx(_=>{var T,I,q,J;return[t.unref(l).render==="slot"&&d.$slots[((T=t.unref(l))==null?void 0:T.slot)||t.unref(l).key]?t.renderSlot(d.$slots,((I=t.unref(l))==null?void 0:I.slot)||t.unref(l).key,t.normalizeProps(t.mergeProps({key:0},_))):t.unref(l).render&&b.value[t.unref(l).render]?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(b.value[t.unref(l).render]),{key:1,row:_.row,col:t.unref(l),onCellChange:s,onCellBlur:u,onCellEnter:f,onClick:g},null,40,["row","col"])):(t.openBlock(),t.createElementBlock("span",{key:2,style:t.normalizeStyle(((q=t.unref(l).renderProps)==null?void 0:q.style)||""),class:t.normalizeClass(((J=t.unref(l).renderProps)==null?void 0:J.class)||""),title:t.unref(k)(_.row,t.unref(l).key)},t.toDisplayString(t.unref(k)(_.row,t.unref(l).key)),15,fe))]}),_:3},16,["label"])):t.createCommentVNode("",!0)}}});function P(n,e){if(!(e!=null&&e.length))return n;const r=new Map(e.map(i=>[i.key,i]));return n.map(i=>{const o=r.get(i.key);return o?{...i,visible:typeof o.visible=="boolean"?o.visible:i.visible}:i})}function pe(n,e){const{cacheKey:r,storage:i=localStorage}=e||{},o=r?i.getItem(r):null,l=t.ref(P(n,o?JSON.parse(o):[]));return t.watch(l,s=>{if(!r)return;const u=s.map(f=>({key:f.key,visible:f.visible,columnOpts:f.columnOpts}));i.setItem(r,JSON.stringify(u))},{deep:!0}),{columns:l,setColumns(s){l.value=P(n,s),r&&i.setItem(r,JSON.stringify(s))},resetColumns(){l.value=n,r&&i.removeItem(r)}}}const z=t.defineComponent({__name:"index",props:{data:{type:Array,default:()=>[]},columns:{type:Array,default:()=>[]},rowKey:{type:String,default:"id"},loading:{type:Boolean,default:!1},permissions:{type:Array,default:()=>[]},cacheKey:String,pagination:{type:Object,default:()=>({})}},emits:["update:columns","cellChange","cellBlur","cellEnter","cell-click"],setup(n,{expose:e,emit:r}){const i=n,o=r,{columns:l}=pe(i.columns,{cacheKey:i.cacheKey??""});t.watch(l,m=>o("update:columns",m),{deep:!0,immediate:!0});const s=(m,w)=>o("cellChange",m,w),u=(m,w)=>{o("cellBlur",m,w)},f=(m,w)=>{console.log("enter"),o("cellEnter",m,w)},g=(m,w)=>{w&&o("cell-click",m,w)},b=t.ref();return e({tableRef:b}),(m,w)=>{const a=t.resolveComponent("el-table"),p=t.resolveDirective("loading");return t.withDirectives((t.openBlock(),t.createBlock(a,t.mergeProps({ref_key:"tableRef",ref:b},m.$attrs,{data:n.data,"row-key":n.rowKey,class:"smart_table"}),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(t.unref(l),y=>(t.openBlock(),t.createBlock(me,{key:y.key,col:y,permissions:n.permissions,pagination:n.pagination,onCellChange:s,onCellBlur:u,onCellEnter:f,onCellClick:g},t.createSlots({_:2},[t.renderList(t.unref(l),S=>({name:S.key,fn:t.withCtx($=>[t.renderSlot(m.$slots,S.key,t.mergeProps({ref_for:!0},$))])}))]),1032,["col","permissions","pagination"]))),128))]),_:3},16,["data","row-key"])),[[p,n.loading]])}}}),W={defaultPagination:{page:1,size:10,total:0},defaultTableProps:{},defaultColumnProps:{}};class ye{constructor(){L(this,"config",{...W})}getConfig(){return{...this.config}}setConfig(e){this.config=this.mergeConfig(this.config,e),e.renderers&&V().registerMultiple(e.renderers)}get(e){return this.config[e]}reset(){this.config={...W}}mergeConfig(e,r){const i={...e};for(const o in r)r[o]&&typeof r[o]=="object"&&!Array.isArray(r[o])?i[o]=this.mergeConfig(e[o]||{},r[o]):i[o]=r[o];return i}}let F=null;function j(){return F||(F=new ye),F}function ge(n){j().setConfig(n)}function he(){return j().getConfig()}function Ce(n,e){return{key:n,...e}}c.SmartTable=z,c.builtInRenderers=O,c.createFunctionalRenderer=B,c.createRenderer=ue,c.default=z,c.defineColumn=Ce,c.getRendererManager=V,c.getSmartTableConfig=he,c.registerBuiltInRenderers=N,c.setSmartTableConfig=ge,c.validateRendererProps=H,c.wrapSFCComponent=M,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
1
|
+
(function(c,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("element-plus"),require("@element-plus/icons-vue")):typeof define=="function"&&define.amd?define(["exports","vue","element-plus","@element-plus/icons-vue"],t):(c=typeof globalThis<"u"?globalThis:c||self,t(c.Vue3SmartTable={},c.Vue,c.ElementPlus,c.ElementPlusIconsVue))})(this,(function(c,t,g,K){"use strict";var be=Object.defineProperty;var we=(c,t,g)=>t in c?be(c,t,{enumerable:!0,configurable:!0,writable:!0,value:g}):c[t]=g;var L=(c,t,g)=>we(c,typeof t!="symbol"?t+"":t,g);var D=document.createElement("style");D.textContent=`.smart_table{width:100%}.st_copy_wrapper:hover .st_copy_btn{display:inline-block!important}.st_copy_btn:hover{transform:translateY(-50%) scale(1.1)}
|
|
2
|
+
/*$vite$:1*/`,document.head.appendChild(D);class U{constructor(){L(this,"renderers",new Map)}register(e,r){this.renderers.has(e)&&process.env.NODE_ENV==="development"&&console.debug(`[SmartTable] Renderer "${e}" already registered, skipping.`),this.renderers.set(e,r)}registerMultiple(e){Object.entries(e).forEach(([r,o])=>{this.renderers.has(r)||this.renderers.set(r,o)})}get(e){return this.renderers.get(e)}has(e){return this.renderers.has(e)}unregister(e){return this.renderers.delete(e)}clear(){this.renderers.clear()}names(){return Array.from(this.renderers.keys())}}let A=null;function V(){return A||(A=new U),A}function M(n){return t.defineComponent({props:["row","col","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>t.h(n,e)}})}function B(n){return t.defineComponent({props:["row","col","onCellChange","onCellBlur","onCellEnter","onClick"],setup(e){return()=>n(e)}})}function H(n,e){if(process.env.NODE_ENV!=="production"&&e)switch(n){case"dict":(!e.options||!Array.isArray(e.options))&&console.warn("[SmartTable] 'dict' renderer requires 'options' array, received:",e.options);break;case"select":!e.options||!Array.isArray(e.options)?console.warn("[SmartTable] 'select' renderer requires 'options' array, received:",e.options):e.options.length===0&&console.warn("[SmartTable] 'select' renderer 'options' array is empty");break;case"map":(!e.options||typeof e.options!="object")&&console.warn("[SmartTable] 'map' renderer requires 'options' object, received:",e.options);break;case"link":(!e.href||typeof e.href!="string")&&console.warn("[SmartTable] 'link' renderer requires 'href' string, received:",e.href);break;case"input-number":e.min!==void 0&&e.max!==void 0&&e.min>e.max&&console.warn(`[SmartTable] 'input-number' renderer: min (${e.min}) should not be greater than max (${e.max})`);break}}function k(n,e){if(!(!n||!e))return e.split(".").reduce((r,o)=>r==null?void 0:r[o],n)}function R(n,e,r){if(!n||!e)return;const o=e.split("."),i=o.pop(),l=o.reduce((s,u)=>(s[u]||(s[u]={}),s[u]),n);l[i]=r}const Y=t.defineComponent({__name:"input",props:{row:{},col:{},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,l=>{R(e.row,e.col.key,l)});const o=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},i=()=>{var l;return(l=e.onCellEnter)==null?void 0:l.call(e,e.row,e.col)};return(l,s)=>{const u=t.resolveComponent("el-input");return t.openBlock(),t.createBlock(u,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":s[0]||(s[0]=f=>r.value=f)},{placeholder:"",size:"small",clearable:!0,...n.col.renderProps},{onBlur:o,onKeyup:t.withKeys(i,["enter"])}),null,16,["modelValue"])}}}),G=t.defineComponent({__name:"inputNumber",props:{row:{},col:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,l=>{var s;R(e.row,e.col.key,l),(s=e.onCellChange)==null||s.call(e,e.row,e.col)});const o=()=>{var l;return(l=e.onCellBlur)==null?void 0:l.call(e,e.row,e.col)},i=()=>{var l;return(l=e.onCellEnter)==null?void 0:l.call(e,e.row,e.col)};return(l,s)=>{const u=t.resolveComponent("el-input-number");return t.openBlock(),t.createBlock(u,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":s[0]||(s[0]=f=>r.value=f)},{min:0,max:99999,controls:!1,size:"small",...n.col.renderProps},{onBlur:o,onKeyup:t.withKeys(i,["enter"])}),null,16,["modelValue"])}}}),Q=t.defineComponent({__name:"select",props:{row:{},col:{},onCellChange:{type:Function},onCellBlur:{type:Function},onCellEnter:{type:Function}},setup(n){const e=n,r=t.ref(k(e.row,e.col.key));t.watch(r,s=>{R(e.row,e.col.key,s)});const o=()=>{var s;return(s=e.onCellChange)==null?void 0:s.call(e,e.row,e.col)},i=()=>{var s;return(s=e.onCellBlur)==null?void 0:s.call(e,e.row,e.col)},l=()=>{var s;return(s=e.onCellEnter)==null?void 0:s.call(e,e.row,e.col)};return(s,u)=>{const f=t.resolveComponent("el-option"),h=t.resolveComponent("el-select");return t.openBlock(),t.createBlock(h,t.mergeProps({modelValue:r.value,"onUpdate:modelValue":u[0]||(u[0]=b=>r.value=b)},{placeholder:"请选择",size:"small",clearable:!0,...n.col.renderProps},{onChange:o,onBlur:i,onKeyup:t.withKeys(l,["enter"])}),{default:t.withCtx(()=>{var b;return[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(((b=n.col.renderProps)==null?void 0:b.options)||[],m=>(t.openBlock(),t.createBlock(f,{key:m.value,label:m.label,value:m.value},null,8,["label","value"]))),128))]}),_:1},16,["modelValue"])}}}),X=M(Y),Z=M(G),v=M(Q),ee=B(n=>{const e=n.col.renderProps||{},r=k(n.row,n.col.key);return t.h(g.ElButton,{type:e.type||"primary",...e,onClick:()=>{var o;return(o=n.onClick)==null?void 0:o.call(n,n.row,n.col)}},()=>e.label||r)}),te=B(n=>{const e=n.col.renderProps||{},r=k(n.row,n.col.key);return t.h("a",{href:e.href||"#",target:e.blank?"_blank":"_self",style:e.style||"color:#409EFF;cursor:pointer;"},e.label||r)}),ne=B(n=>{var r;const e=k(n.row,n.col.key);return t.h("div",{class:"line-clamp-2",innerHTML:e??"",...((r=n.col)==null?void 0:r.renderProps)||{}})}),re=B(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps??{},o={position:"absolute",right:"-5px",top:"50%",transform:"translateY(-50%)",cursor:"pointer",display:"none","font-size":"12px",color:r.iconColor||"#409EFF","user-select":"none"},i={"padding-right":"10px",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":r.lineClamp??2,overflow:"hidden",...r.textStyles};return t.h("div",{class:"st_copy_wrapper",style:"width: 100%; position: relative; display: inline-block;"},[t.h("span",{class:`st_copy_text ${r.textClass??""}`,style:i,title:e},e),e&&t.h("span",{class:"st_copy_btn",style:o,title:r.copyTitle||"复制",onClick:()=>{if(e)try{if(navigator.clipboard&&navigator.clipboard.writeText)navigator.clipboard.writeText(e).then(()=>{g.ElMessage.success(r.successText??"复制成功")}).catch(()=>{g.ElMessage.error(r.errorText??"复制失败")});else{const l=document.createElement("textarea");l.value=e,l.style.position="fixed",l.style.opacity="0",document.body.appendChild(l),l.select();const s=document.execCommand("copy");document.body.removeChild(l),s?g.ElMessage.success(r.successText??"复制成功"):g.ElMessage.error(r.errorText??"复制失败")}}catch{g.ElMessage.error(r.errorText??"复制失败")}}},[t.h(K.DocumentCopy,{style:"width: 1em; height: 1em;"})])].filter(Boolean))}),le=B(n=>{var s;const e=k(n.row,n.col.key)??"",r=((s=n.col)==null?void 0:s.renderProps)||{},i=e?Array.isArray(e)?e.filter(u=>u&&typeof u=="string"):[e]:[];if(i.length===0)return r.placeholder||"";const l={width:r.width||"80px",height:r.height||"80px",marginRight:i.length>1?"4px":"0",...r.style||{}};return i.length===1?t.h(g.ElImage,{src:i[0],previewSrcList:r.previewSrcList||i,fit:r.fit||"contain",style:l,...r}):t.h("div",{class:"st_img_wrapper",style:"display: flex; align-items: center; position: relative"},[t.h(g.ElImage,{src:i[0],previewSrcList:r.previewSrcList||i,fit:r.fit||"contain",style:l,...r}),i.length>1&&t.h("span",{class:"st_img_total",style:"position: absolute; top: 0; right: 0; ",title:`${i.length}`},[t.h(K.CopyDocument,{style:"width: 1em; height: 1em; "})])])}),oe=B(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps||{},o=r.options??[],i=r.showValue??!1;if(e==null||e==="")return"";const l=Array.isArray(e)?e.map(String):[String(e)],s=o.filter(h=>l.includes(String(h.value))),u=l.filter(h=>!o.some(b=>String(b.value)===h)),f=s.map((h,b)=>t.h(g.ElTag,{key:h.value,type:h.listClass,class:h.cssClass,disableTransitions:!0},{default:()=>h.label+" "}));return i&&u.length>0&&f.push(t.h("span",{},u.join(" "))),t.h("div",{},f)}),ie=B(n=>{var o;const e=k(n.row,n.col.key)??"",r=((o=n.col.renderProps)==null?void 0:o.options)??{};return e!=null?r[e]??"":""});function se(n){return typeof n.formatter=="function"}const ae=B(n=>{var i;const{col:e,row:r}=n,o=k(n.row,n.col.key)??"";return se(e)?(i=e.formatter)==null?void 0:i.call(e,o,r):o??""}),ce=B(n=>{const e=k(n.row,n.col.key)??"",r=n.col.renderProps||{};return e?/^https?:\/\//.test(e)?t.h(g.ElImage,{src:e,previewSrcList:[e],fit:"contain",style:"width:40px;height:40px",...r}):/^\s*<svg[\s\S]*<\/svg>\s*$/.test(e)?t.h("div",{innerHTML:e,style:`width:40px;height:40px;display:inline-block;${r.style||""}`,...r}):t.h("i",{class:e,style:`font-size:20px;${r.style||""}`,...r}):""}),O={input:X,"input-number":Z,select:v,button:ee,link:te,html:ne,copy:re,img:le,dict:oe,map:ie,formatter:ae,icon:ce};function N(n){n.registerMultiple(O)}function ue(){return O}function de(n,e=10,r=[]){const i="*:*:*",l=a=>{if(!a)return!0;const p=Array.isArray(a)?a:[a];return r.some(y=>y===i||p.includes(y))},s=t.computed(()=>n.some(a=>l(a.permission))),u=t.computed(()=>n.filter(p=>l(p.permission)).slice(0,e).reduce((p,y)=>p+(y.width??60),0)),f=(a,p)=>l(a.permission)&&(a.visible?a.visible(p):!0),h=a=>n.filter(y=>f(y,a)).slice(0,e).reduce((y,E)=>y+(E.width??60),0);return{hasAnyButton:s,optWidth:u,hasAnyVisibleButton:a=>a!=null&&a.length?a.some(p=>n.some(y=>f(y,p))):!1,getMaxOptWidth:a=>a!=null&&a.length?a.reduce((p,y)=>Math.max(p,h(y)),0):u.value,getVisibleButtons:a=>n.filter(p=>f(p,a)).slice(0,e)}}const fe=["title"],me=t.defineComponent({__name:"index",props:{col:{type:Object,required:!0},permissions:{type:Array,default:()=>[]},pagination:{type:Object,default:()=>({})}},emits:["cellBlur","cellEnter","cellChange","cellClick"],setup(n,{emit:e}){const r=n,o=e,i=d=>{var S,_;const C=(S=r.pagination)==null?void 0:S.page,x=(_=r.pagination)==null?void 0:_.size;return C&&x?(C-1)*x+d+1:d+1},{col:l}=t.toRefs(r),s=(d,C)=>o("cellChange",d,C),u=(d,C)=>o("cellBlur",d,C),f=(d,C)=>o("cellEnter",d,C),h=(d,C)=>o("cellClick",d,C);N(V());const b=t.computed(()=>{const d=V(),C={};return d.names().forEach(x=>{const S=d.get(x);S&&(C[x]=S)}),C}),{hasAnyButton:m,hasAnyVisibleButton:w,optWidth:a,getMaxOptWidth:p,getVisibleButtons:y}=de(l.value.buttons||[],l.value.maxbtn??10,r.permissions||[]),E=t.computed(()=>(l.value.buttons||[]).length?(l.value.__rows||[]).length?w(l.value.__rows||[]):m.value:!1),$=t.computed(()=>l.value.__rows?p(l.value.__rows):a.value);function ke(d){return!(d.type==="selection"||d.type==="index"||d.type==="operation"&&!E.value||d.visible===!1)}return(d,C)=>{const x=t.resolveComponent("el-table-column"),S=t.resolveComponent("el-button");return t.unref(l).type==="selection"?(t.openBlock(),t.createBlock(x,t.mergeProps({key:0,type:"selection"},t.unref(l).columnProps),null,16)):t.unref(l).type==="index"?(t.openBlock(),t.createBlock(x,t.mergeProps({key:1,type:"index",label:t.unref(l).label||"#",align:"center"},t.unref(l).columnProps),{default:t.withCtx(({$index:_})=>[t.createTextVNode(t.toDisplayString(i(_)),1)]),_:1},16,["label"])):t.unref(l).type==="operation"&&E.value?(t.openBlock(),t.createBlock(x,t.mergeProps({key:2,label:t.unref(l).label||"操作",align:"center"},{...t.unref(l).columnProps,width:$.value}),{default:t.withCtx(({row:_})=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(t.unref(y)(_),T=>(t.openBlock(),t.createBlock(S,{key:T.label,type:T.type||"primary",link:"",onClick:I=>T.action(_)},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(T.label),1)]),_:2},1032,["type","onClick"]))),128))]),_:1},16,["label"])):ke(t.unref(l))?(t.openBlock(),t.createBlock(x,t.mergeProps({key:3,label:t.unref(l).label,align:"center"},t.unref(l).columnProps||{}),{default:t.withCtx(_=>{var T,I,q,J;return[t.unref(l).render==="slot"&&d.$slots[((T=t.unref(l))==null?void 0:T.slot)||t.unref(l).key]?t.renderSlot(d.$slots,((I=t.unref(l))==null?void 0:I.slot)||t.unref(l).key,t.normalizeProps(t.mergeProps({key:0},_))):t.unref(l).render&&b.value[t.unref(l).render]?(t.openBlock(),t.createBlock(t.resolveDynamicComponent(b.value[t.unref(l).render]),{key:1,row:_.row,col:t.unref(l),onCellChange:s,onCellBlur:u,onCellEnter:f,onClick:h},null,40,["row","col"])):(t.openBlock(),t.createElementBlock("span",{key:2,style:t.normalizeStyle(((q=t.unref(l).renderProps)==null?void 0:q.style)||""),class:t.normalizeClass(((J=t.unref(l).renderProps)==null?void 0:J.class)||""),title:t.unref(k)(_.row,t.unref(l).key)},t.toDisplayString(t.unref(k)(_.row,t.unref(l).key)),15,fe))]}),_:3},16,["label"])):t.createCommentVNode("",!0)}}});function P(n,e){if(!(e!=null&&e.length))return n;const r=new Map(e.map(o=>[o.key,o]));return n.map(o=>{const i=r.get(o.key);return i?{...o,visible:typeof i.visible=="boolean"?i.visible:o.visible}:o})}function pe(n,e){const{cacheKey:r,storage:o=localStorage}=e||{},i=r?o.getItem(r):null,l=t.ref(P(n,i?JSON.parse(i):[]));return t.watch(l,s=>{if(!r)return;const u=s.map(f=>({key:f.key,visible:f.visible,columnOpts:f.columnOpts}));o.setItem(r,JSON.stringify(u))},{deep:!0}),{columns:l,setColumns(s){l.value=P(n,s),r&&o.setItem(r,JSON.stringify(s))},resetColumns(){l.value=n,r&&o.removeItem(r)}}}const z=t.defineComponent({__name:"index",props:{data:{type:Array,default:()=>[]},columns:{type:Array,default:()=>[]},rowKey:{type:String,default:"id"},loading:{type:Boolean,default:!1},permissions:{type:Array,default:()=>[]},cacheKey:String,pagination:{type:Object,default:()=>({})}},emits:["update:columns","cellChange","cellBlur","cellEnter","cell-click"],setup(n,{expose:e,emit:r}){const o=n,i=r,{columns:l}=pe(o.columns,{cacheKey:o.cacheKey??""});t.watch(l,m=>i("update:columns",m),{deep:!0,immediate:!0});const s=(m,w)=>i("cellChange",m,w),u=(m,w)=>{i("cellBlur",m,w)},f=(m,w)=>{console.log("enter"),i("cellEnter",m,w)},h=(m,w)=>{w&&i("cell-click",m,w)},b=t.ref();return e({tableRef:b}),(m,w)=>{const a=t.resolveComponent("el-table"),p=t.resolveDirective("loading");return t.withDirectives((t.openBlock(),t.createBlock(a,t.mergeProps({ref_key:"tableRef",ref:b},m.$attrs,{data:n.data,"row-key":n.rowKey,class:"smart_table"}),{default:t.withCtx(()=>[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(t.unref(l),y=>(t.openBlock(),t.createBlock(me,{key:y.key,col:y,permissions:n.permissions,pagination:n.pagination,onCellChange:s,onCellBlur:u,onCellEnter:f,onCellClick:h},t.createSlots({_:2},[t.renderList(t.unref(l),E=>({name:E.key,fn:t.withCtx($=>[t.renderSlot(m.$slots,E.key,t.mergeProps({ref_for:!0},$))])}))]),1032,["col","permissions","pagination"]))),128))]),_:3},16,["data","row-key"])),[[p,n.loading]])}}}),W={defaultPagination:{page:1,size:10,total:0},defaultTableProps:{},defaultColumnProps:{}};class ye{constructor(){L(this,"config",{...W})}getConfig(){return{...this.config}}setConfig(e){this.config=this.mergeConfig(this.config,e),e.renderers&&V().registerMultiple(e.renderers)}get(e){return this.config[e]}reset(){this.config={...W}}mergeConfig(e,r){const o={...e};for(const i in r)r[i]&&typeof r[i]=="object"&&!Array.isArray(r[i])?o[i]=this.mergeConfig(e[i]||{},r[i]):o[i]=r[i];return o}}let F=null;function j(){return F||(F=new ye),F}function he(n){j().setConfig(n)}function ge(){return j().getConfig()}function Ce(n,e){return{key:n,...e}}c.SmartTable=z,c.builtInRenderers=O,c.createFunctionalRenderer=B,c.createRenderer=ue,c.default=z,c.defineColumn=Ce,c.getRendererManager=V,c.getSmartTableConfig=ge,c.registerBuiltInRenderers=N,c.setSmartTableConfig=he,c.validateRendererProps=H,c.wrapSFCComponent=M,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
3
3
|
//# sourceMappingURL=vue3-smart-table.umd.js.map
|