diff --git a/packages/editor/src/index.ts b/packages/editor/src/index.ts index 693532ce..62e73956 100644 --- a/packages/editor/src/index.ts +++ b/packages/editor/src/index.ts @@ -37,6 +37,7 @@ export { default as TMagicCodeEditor } from './layouts/CodeEditor.vue'; export { default as editorService } from './services/editor'; export { default as propsService } from './services/props'; export { default as historyService } from './services/history'; +export { default as storageService } from './services/storage'; export { default as eventsService } from './services/events'; export { default as uiService } from './services/ui'; export { default as ComponentListPanel } from './layouts/sidebar/ComponentListPanel.vue'; diff --git a/packages/editor/src/layouts/workspace/ViewerMenu.vue b/packages/editor/src/layouts/workspace/ViewerMenu.vue index 54fc2154..040f30fa 100644 --- a/packages/editor/src/layouts/workspace/ViewerMenu.vue +++ b/packages/editor/src/layouts/workspace/ViewerMenu.vue @@ -11,6 +11,7 @@ import StageCore from '@tmagic/stage'; import { isPage } from '@tmagic/utils'; import ContentMenu from '@editor/components/ContentMenu.vue'; +import storageService from '@editor/services/storage'; import { LayerOffset, Layout, MenuItem, Services } from '@editor/type'; import { COPY_STORAGE_KEY } from '@editor/utils/editor'; @@ -141,8 +142,8 @@ export default defineComponent({ ...stageContentMenu, ]); - onMounted(() => { - const data = globalThis.localStorage.getItem(COPY_STORAGE_KEY); + onMounted(async () => { + const data = await storageService.getItem(COPY_STORAGE_KEY); canPaste.value = data !== 'undefined' && !!data; }); diff --git a/packages/editor/src/services/editor.ts b/packages/editor/src/services/editor.ts index 5c4b07c8..ee97706a 100644 --- a/packages/editor/src/services/editor.ts +++ b/packages/editor/src/services/editor.ts @@ -26,6 +26,7 @@ import StageCore from '@tmagic/stage'; import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils'; import historyService, { StepValue } from '@editor/services/history'; +import storageService from '@editor/services/storage'; import type { AddMNode, EditorNodeInfo, PastePosition, StoreState } from '@editor/type'; import { LayerOffset, Layout } from '@editor/type'; import { @@ -482,7 +483,7 @@ class Editor extends BaseService { * @returns 组件节点配置 */ public async copy(config: MNode | MNode[]): Promise { - globalThis.localStorage.setItem(COPY_STORAGE_KEY, serialize(Array.isArray(config) ? config : [config])); + await storageService.setItem(COPY_STORAGE_KEY, serialize(Array.isArray(config) ? config : [config])); } /** @@ -491,7 +492,7 @@ class Editor extends BaseService { * @returns 添加后的组件节点配置 */ public async paste(position: PastePosition = {}): Promise { - const configStr = globalThis.localStorage.getItem(COPY_STORAGE_KEY); + const configStr = await storageService.getItem(COPY_STORAGE_KEY); // eslint-disable-next-line prefer-const let config: any = {}; if (!configStr) { diff --git a/packages/editor/src/services/storage.ts b/packages/editor/src/services/storage.ts new file mode 100644 index 00000000..0edc3e56 --- /dev/null +++ b/packages/editor/src/services/storage.ts @@ -0,0 +1,61 @@ +import BaseService from './BaseService'; + +/** + * 数据存储服务 + */ +export class WebStorage extends BaseService { + constructor() { + super(['getStorage', 'clear', 'getItem', 'removeItem', 'setItem']); + } + + /** + * 获取数据存储对象,可以通过 + * const storageService = new StorageService(); + * storageService.use({ + * // 替换存储对象为 sessionStorage + * async getStorage(): Promise { + * return window.sessionStorage; + * }, + * }); + */ + public async getStorage(): Promise { + return globalThis.localStorage; + } + /** + * 清理,支持storageService.use + */ + public async clear(): Promise { + const storage = await this.getStorage(); + storage.clear(); + } + /** + * 获取存储项,支持storageService.use + */ + public async getItem(key: string): Promise { + const storage = await this.getStorage(); + return storage.getItem(key); + } + /** + * 获取指定索引位置的key + */ + public async key(index: number): Promise { + const storage = await this.getStorage(); + return storage.key(index); + } + /** + * 移除存储项,支持storageService.use + */ + public async removeItem(key: string): Promise { + const storage = await this.getStorage(); + storage.removeItem(key); + } + /** + * 设置存储项,支持storageService.use + */ + public async setItem(key: string, value: string): Promise { + const storage = await this.getStorage(); + storage.setItem(key, value); + } +} +export type StorageService = WebStorage; +export default new WebStorage(); diff --git a/packages/editor/src/type.ts b/packages/editor/src/type.ts index 1e6eb63d..b09d77ca 100644 --- a/packages/editor/src/type.ts +++ b/packages/editor/src/type.ts @@ -28,6 +28,7 @@ import type { EditorService } from '@editor/services/editor'; import type { EventsService } from '@editor/services/events'; import type { HistoryService } from '@editor/services/history'; import type { PropsService } from '@editor/services/props'; +import type { StorageService } from '@editor/services/storage'; import type { UiService } from '@editor/services/ui'; export type BeforeAdd = (config: MNode, parent: MContainer) => Promise | MNode; @@ -40,6 +41,7 @@ export interface InstallOptions { export interface Services { editorService: EditorService; historyService: HistoryService; + storageService: StorageService; eventsService: EventsService; propsService: PropsService; componentListService: ComponentListService; diff --git a/packages/editor/tests/unit/services/editor.spec.ts b/packages/editor/tests/unit/services/editor.spec.ts index 3fbd9fc4..5d9fe1dc 100644 --- a/packages/editor/tests/unit/services/editor.spec.ts +++ b/packages/editor/tests/unit/services/editor.spec.ts @@ -23,6 +23,7 @@ import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema'; import { NodeType } from '@tmagic/schema'; import editorService from '@editor/services/editor'; +import storageService from '@editor/services/storage'; import { COPY_STORAGE_KEY } from '@editor/utils'; // mock window.localStage @@ -352,7 +353,7 @@ describe('copy', () => { test('正常', async () => { const node = editorService.getNodeById(NodeId.NODE_ID2); await editorService.copy(node!); - const str = globalThis.localStorage.getItem(COPY_STORAGE_KEY); + const str = await storageService.getItem(COPY_STORAGE_KEY); expect(str).toBe(JSON.stringify([node])); }); });