diff --git a/packages/vue-vtable/src/edit/editor.ts b/packages/vue-vtable/src/edit/editor.ts index 25d681bca8..710523959c 100644 --- a/packages/vue-vtable/src/edit/editor.ts +++ b/packages/vue-vtable/src/edit/editor.ts @@ -1,7 +1,6 @@ import { isValid } from '@visactor/vutils'; import { isVNode, render } from 'vue'; -import { VTable } from '..'; -import type { IBasicColumnBodyDefine } from '@visactor/vtable/src/ts-types/list-table/define/basic-define'; +import { TYPES } from '@visactor/vtable'; /** 渲染式编辑器参数 */ export interface DynamicRenderEditorParams { @@ -43,7 +42,10 @@ export interface ValidateValueParams { table?: any; } -interface ColumnDefine extends IBasicColumnBodyDefine { +/** 必要列配置 */ +interface ColumnDefine { + /** 列唯一标识 */ + key?: string; /** 渲染式编辑器配置 */ editConfig?: DynamicRenderEditorConfig; } @@ -118,8 +120,9 @@ export class DynamicRenderEditor { return false; } const define = table.getBodyColumnDefine(col, row) as ColumnDefine; - const { key, editConfig } = define || {}; + const { editConfig } = define || {}; const { id } = table; + const key = this.getColumnKeyField(define); if (!isValid(key) || !isValid(id)) { return false; } @@ -130,7 +133,7 @@ export class DynamicRenderEditor { table.showTooltip(col, row, { // TODO 多语言 content: editConfig.disablePrompt || 'This field is not allowed to be edited', - referencePosition: { rect: referencePosition?.rect, placement: VTable.TYPES.Placement.top }, + referencePosition: { rect: referencePosition?.rect, placement: TYPES.Placement.top }, style: { bgColor: 'black', color: 'white', @@ -172,6 +175,16 @@ export class DynamicRenderEditor { } return true; } + /** + * @description: 获取渲染式编辑器的列配置主键 + * @param {any} column + * @return {*} + */ + getColumnKeyField(column: any) { + const { field, key } = column || {}; + // 兼容取 field + return isValid(key) ? key : field; + } getValue() { return this.currentValue; @@ -208,7 +221,7 @@ export class DynamicRenderEditor { const rect = table.getVisibleCellRangeRelativeRect({ col, row }); table.showTooltip(col, row, { content: editConfig.invalidPrompt || 'invalid', - referencePosition: { rect, placement: VTable.TYPES.Placement.top }, + referencePosition: { rect, placement: TYPES.Placement.top }, style: { bgColor: 'red', color: 'white', diff --git a/packages/vue-vtable/src/edit/util.ts b/packages/vue-vtable/src/edit/util.ts index c1966bec47..90549ba3fc 100644 --- a/packages/vue-vtable/src/edit/util.ts +++ b/packages/vue-vtable/src/edit/util.ts @@ -5,44 +5,13 @@ * @LastEditTime: 2025-03-03 20:17:33 * @Description: 集成编辑器工具方法 */ - -import { VTable } from '..'; +import { register } from '@visactor/vtable'; import { DynamicRenderEditor } from './editor'; import { isValid } from '@visactor/vutils'; /** 动态渲染编辑器名称 */ const DYNAMIC_RENDER_EDITOR = 'dynamic-render-editor'; -/** - * @description: 动态渲染式编辑器 - * @param {any} table - * @param {VTable} option - * @return {*} - */ -export function resolveRenderEditor(table: any, option: VTable.ListTableConstructorOptions) { - if (!isValid(table?.id) || !option?.columns?.length) { - return; - } - const { id } = table; - // 移除原本已存在的编辑器 - const rawRenderEditor = getRenderEditor(); - if (rawRenderEditor) { - rawRenderEditor.removeNode(id); - } - if (option.columns.some(x => checkRenderEditor(x))) { - // 需要注册编辑器 - const renderEditor = rawRenderEditor || getRenderEditor(true); - option.columns.forEach((column: any) => { - if (!checkRenderEditor(column)) { - return; - } - const { key, getEditCustomNode } = column; - renderEditor.registerNode(id, key, getEditCustomNode); - delete column.editCustomNode; - }); - } -} - /** * @description: 校验动态渲染式编辑器 * @param {any} column @@ -50,7 +19,8 @@ export function resolveRenderEditor(table: any, option: VTable.ListTableConstruc * @return {*} */ export function checkRenderEditor(column: any, getEditCustomNode?: any) { - const { key, editor } = column || {}; + const { editor } = column || {}; + const key = getRenderEditorColumnKeyField(column); if (!isValid(key) || editor !== DYNAMIC_RENDER_EDITOR) { return false; } @@ -61,27 +31,28 @@ export function checkRenderEditor(column: any, getEditCustomNode?: any) { return typeof column.getEditCustomNode === 'function'; } +/** + * @description: 获取渲染式编辑器的列配置主键 + * @param {any} column + * @return {*} + */ +export function getRenderEditorColumnKeyField(column: any) { + const { field, key } = column || {}; + // 兼容取 field + return isValid(key) ? key : field; +} + /** * @description: 获取动态渲染式编辑器 * @param {boolean} create * @return {*} */ -function getRenderEditor(create?: boolean) { - let renderEditor = VTable.register.editor(DYNAMIC_RENDER_EDITOR) as DynamicRenderEditor; +export function getRenderEditor(create?: boolean) { + let renderEditor = register.editor(DYNAMIC_RENDER_EDITOR) as DynamicRenderEditor; if (!renderEditor && !!create) { // 注册自定义编辑器 renderEditor = new DynamicRenderEditor(); - VTable.register.editor(DYNAMIC_RENDER_EDITOR, renderEditor); + register.editor(DYNAMIC_RENDER_EDITOR, renderEditor); } return renderEditor; } - -/** - * @description: 释放动态渲染式编辑器 - * @param {number} tableId - * @return {*} - */ -export function releaseRenderEditor(tableId?: number | string) { - const renderEditor = getRenderEditor(); - renderEditor?.release(tableId); -} diff --git a/packages/vue-vtable/src/hooks/index.ts b/packages/vue-vtable/src/hooks/index.ts new file mode 100644 index 0000000000..19511a2e8b --- /dev/null +++ b/packages/vue-vtable/src/hooks/index.ts @@ -0,0 +1,2 @@ +export * from './useEditorRender'; +export * from './useCellRender'; diff --git a/packages/vue-vtable/src/hooks/useCellRender.ts b/packages/vue-vtable/src/hooks/useCellRender.ts new file mode 100644 index 0000000000..1fecc917de --- /dev/null +++ b/packages/vue-vtable/src/hooks/useCellRender.ts @@ -0,0 +1,22 @@ +import type { Ref } from 'vue'; +import { watchEffect } from 'vue'; +import { VTableVueAttributePlugin } from '../components/custom/vtable-vue-attribute-plugin'; + +/** + * 自定义单元格渲染器 + * @param props + * @param tableRef + */ +export function useCellRender(props: any, tableRef: Ref) { + watchEffect(() => { + if (!props?.customConfig?.createReactContainer) { + // 未开启自定义容器 + return; + } + if (!tableRef.value) { + return; + } + // 注册 vtable-vue 自定义组件集成插件 + tableRef.value.scenegraph.stage.pluginService.register(new VTableVueAttributePlugin()); + }); +} diff --git a/packages/vue-vtable/src/hooks/useEditorRender.ts b/packages/vue-vtable/src/hooks/useEditorRender.ts new file mode 100644 index 0000000000..e4165a7c68 --- /dev/null +++ b/packages/vue-vtable/src/hooks/useEditorRender.ts @@ -0,0 +1,69 @@ +import type { Ref } from 'vue'; +import { computed, onBeforeUnmount, watchEffect } from 'vue'; +import { isArray, isObject, isValid } from '@visactor/vutils'; +import { checkRenderEditor, getRenderEditor, getRenderEditorColumnKeyField } from '../edit'; + +/** + * 编辑渲染器 + * @param props + * @param tableRef + */ +export function useEditorRender(props: any, tableRef: Ref) { + /** 需要渲染编辑器的列 */ + const validColumns = computed(() => { + const columns = props.options?.columns; + if (!isArray(columns)) { + return []; + } + return (columns as any[]).filter(col => !!isObject(col) && !!checkRenderEditor(col)); + }); + watchEffect(() => { + resolveRenderEditor(); + }); + onBeforeUnmount(() => { + releaseRenderEditor(); + }); + /** + * @description: 动态渲染式编辑器 + * @return {*} + */ + function resolveRenderEditor() { + const id = getTableId(); + if (!isValid(id)) { + return; + } + // 移除原本已存在的编辑器 + let renderEditor = getRenderEditor(); + if (renderEditor) { + renderEditor.removeNode(id); + } else if (validColumns.value.length > 0) { + // 注册编辑器 + renderEditor = getRenderEditor(true); + } + validColumns.value.forEach(column => { + const { getEditCustomNode } = column; + const key = getRenderEditorColumnKeyField(column); + renderEditor.registerNode(id, key, getEditCustomNode); + delete column.editCustomNode; + }); + } + /** + * @description: 释放动态渲染式编辑器 + * @return {*} + */ + function releaseRenderEditor() { + const id = getTableId(); + if (!isValid(id)) { + return; + } + const renderEditor = getRenderEditor(); + renderEditor?.release(id); + } + /** + * @description: 获取表格 id + * @return {*} + */ + function getTableId() { + return tableRef.value?.id; + } +} diff --git a/packages/vue-vtable/src/tables/base-table.vue b/packages/vue-vtable/src/tables/base-table.vue index eee24b1dff..cb0cee7a3a 100644 --- a/packages/vue-vtable/src/tables/base-table.vue +++ b/packages/vue-vtable/src/tables/base-table.vue @@ -5,13 +5,11 @@