mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-05-05 17:56:54 +08:00
feat(editor): 复制组件时收集依赖性能优化改造
This commit is contained in:
parent
50d238a48c
commit
cd191f6815
@ -114,7 +114,12 @@ export default class Watcher {
|
|||||||
* @param deep 是否需要收集子节点
|
* @param deep 是否需要收集子节点
|
||||||
* @param type 强制收集指定类型的依赖
|
* @param type 强制收集指定类型的依赖
|
||||||
*/
|
*/
|
||||||
public collect(nodes: TargetNode[], depExtendedData: DepExtendedData = {}, deep = false, type?: DepTargetType) {
|
public collect(
|
||||||
|
nodes: TargetNode[],
|
||||||
|
depExtendedData: DepExtendedData = {},
|
||||||
|
deep = false,
|
||||||
|
type?: DepTargetType | string,
|
||||||
|
) {
|
||||||
this.collectByCallback(nodes, type, ({ node, target }) => {
|
this.collectByCallback(nodes, type, ({ node, target }) => {
|
||||||
this.removeTargetDep(target, node);
|
this.removeTargetDep(target, node);
|
||||||
this.collectItem(node, target, depExtendedData, deep);
|
this.collectItem(node, target, depExtendedData, deep);
|
||||||
@ -123,7 +128,7 @@ export default class Watcher {
|
|||||||
|
|
||||||
public collectByCallback(
|
public collectByCallback(
|
||||||
nodes: TargetNode[],
|
nodes: TargetNode[],
|
||||||
type: DepTargetType | undefined,
|
type: DepTargetType | string | undefined,
|
||||||
cb: (data: { node: TargetNode; target: Target }) => void,
|
cb: (data: { node: TargetNode; target: Target }) => void,
|
||||||
) {
|
) {
|
||||||
traverseTarget(
|
traverseTarget(
|
||||||
@ -144,7 +149,7 @@ export default class Watcher {
|
|||||||
* 清除所有目标的依赖
|
* 清除所有目标的依赖
|
||||||
* @param nodes 需要清除依赖的节点
|
* @param nodes 需要清除依赖的节点
|
||||||
*/
|
*/
|
||||||
public clear(nodes?: TargetNode[], type?: DepTargetType) {
|
public clear(nodes?: TargetNode[], type?: DepTargetType | string) {
|
||||||
let { targetsList } = this;
|
let { targetsList } = this;
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
@ -179,7 +184,7 @@ export default class Watcher {
|
|||||||
* @param type 类型
|
* @param type 类型
|
||||||
* @param nodes 需要清除依赖的节点
|
* @param nodes 需要清除依赖的节点
|
||||||
*/
|
*/
|
||||||
public clearByType(type: DepTargetType, nodes?: TargetNode[]) {
|
public clearByType(type: DepTargetType | string, nodes?: TargetNode[]) {
|
||||||
this.clear(nodes, type);
|
this.clear(nodes, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,14 +28,6 @@ export interface TargetOptions {
|
|||||||
isCollectByDefault?: boolean;
|
isCollectByDefault?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CustomTargetOptions {
|
|
||||||
isTarget: IsTarget;
|
|
||||||
name?: string;
|
|
||||||
initialDeps?: DepData;
|
|
||||||
/** 是否默认收集,默认为true,当值为false时需要传入type参数给collect方法才会被收集 */
|
|
||||||
isCollectByDefault?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TargetList {
|
export interface TargetList {
|
||||||
[type: string]: {
|
[type: string]: {
|
||||||
[targetId: string | number]: Target;
|
[targetId: string | number]: Target;
|
||||||
|
@ -193,7 +193,11 @@ export const createDataSourceMethodTarget = (ds: DataSourceSchema, initialDeps:
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const traverseTarget = (targetsList: TargetList, cb: (target: Target) => void, type?: DepTargetType) => {
|
export const traverseTarget = (
|
||||||
|
targetsList: TargetList,
|
||||||
|
cb: (target: Target) => void,
|
||||||
|
type?: DepTargetType | string,
|
||||||
|
) => {
|
||||||
Object.values(targetsList).forEach((targets) => {
|
Object.values(targetsList).forEach((targets) => {
|
||||||
Object.values(targets).forEach((target) => {
|
Object.values(targets).forEach((target) => {
|
||||||
if (type && target.type !== type) {
|
if (type && target.type !== type) {
|
||||||
|
@ -20,7 +20,7 @@ import { reactive } from 'vue';
|
|||||||
import { cloneDeep, get, keys, pick } from 'lodash-es';
|
import { cloneDeep, get, keys, pick } from 'lodash-es';
|
||||||
import type { Writable } from 'type-fest';
|
import type { Writable } from 'type-fest';
|
||||||
|
|
||||||
import { type CustomTargetOptions, Target, Watcher } from '@tmagic/dep';
|
import { Target, type TargetOptions, Watcher } from '@tmagic/dep';
|
||||||
import type { ColumnConfig } from '@tmagic/form';
|
import type { ColumnConfig } from '@tmagic/form';
|
||||||
import type { CodeBlockContent, CodeBlockDSL, Id, MNode } from '@tmagic/schema';
|
import type { CodeBlockContent, CodeBlockDSL, Id, MNode } from '@tmagic/schema';
|
||||||
|
|
||||||
@ -257,13 +257,12 @@ class CodeBlock extends BaseService {
|
|||||||
* @param config 组件节点配置
|
* @param config 组件节点配置
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public copyWithRelated(config: MNode | MNode[], collectorOptions?: CustomTargetOptions): void {
|
public copyWithRelated(config: MNode | MNode[], collectorOptions?: TargetOptions): void {
|
||||||
const copyNodes: MNode[] = Array.isArray(config) ? config : [config];
|
const copyNodes: MNode[] = Array.isArray(config) ? config : [config];
|
||||||
const copyData: CodeBlockDSL = {};
|
const copyData: CodeBlockDSL = {};
|
||||||
|
|
||||||
if (collectorOptions && typeof collectorOptions.isTarget === 'function') {
|
if (collectorOptions && typeof collectorOptions.isTarget === 'function') {
|
||||||
const customTarget = new Target({
|
const customTarget = new Target({
|
||||||
id: 'related-code-when-copy',
|
|
||||||
...collectorOptions,
|
...collectorOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -271,11 +270,7 @@ class CodeBlock extends BaseService {
|
|||||||
|
|
||||||
coperWatcher.addTarget(customTarget);
|
coperWatcher.addTarget(customTarget);
|
||||||
|
|
||||||
coperWatcher.collect(
|
coperWatcher.collect(copyNodes, {}, true, collectorOptions.type);
|
||||||
copyNodes.map((node) => ({ id: `${node.id}`, name: `${node.name || node.id}` })),
|
|
||||||
{},
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
Object.keys(customTarget.deps).forEach((nodeId: Id) => {
|
Object.keys(customTarget.deps).forEach((nodeId: Id) => {
|
||||||
const node = editorService.getNodeById(nodeId);
|
const node = editorService.getNodeById(nodeId);
|
||||||
|
@ -3,7 +3,7 @@ import { cloneDeep, get } from 'lodash-es';
|
|||||||
import { Writable } from 'type-fest';
|
import { Writable } from 'type-fest';
|
||||||
|
|
||||||
import type { EventOption } from '@tmagic/core';
|
import type { EventOption } from '@tmagic/core';
|
||||||
import { type CustomTargetOptions, Target, Watcher } from '@tmagic/dep';
|
import { Target, type TargetOptions, Watcher } from '@tmagic/dep';
|
||||||
import type { FormConfig } from '@tmagic/form';
|
import type { FormConfig } from '@tmagic/form';
|
||||||
import type { DataSourceSchema, Id, MNode } from '@tmagic/schema';
|
import type { DataSourceSchema, Id, MNode } from '@tmagic/schema';
|
||||||
import { guid, toLine } from '@tmagic/utils';
|
import { guid, toLine } from '@tmagic/utils';
|
||||||
@ -162,13 +162,12 @@ class DataSource extends BaseService {
|
|||||||
* @param config 组件节点配置
|
* @param config 组件节点配置
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public copyWithRelated(config: MNode | MNode[], collectorOptions?: CustomTargetOptions): void {
|
public copyWithRelated(config: MNode | MNode[], collectorOptions?: TargetOptions): void {
|
||||||
const copyNodes: MNode[] = Array.isArray(config) ? config : [config];
|
const copyNodes: MNode[] = Array.isArray(config) ? config : [config];
|
||||||
const copyData: DataSourceSchema[] = [];
|
const copyData: DataSourceSchema[] = [];
|
||||||
|
|
||||||
if (collectorOptions && typeof collectorOptions.isTarget === 'function') {
|
if (collectorOptions && typeof collectorOptions.isTarget === 'function') {
|
||||||
const customTarget = new Target({
|
const customTarget = new Target({
|
||||||
id: 'related-ds-when-copy',
|
|
||||||
...collectorOptions,
|
...collectorOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -176,11 +175,7 @@ class DataSource extends BaseService {
|
|||||||
|
|
||||||
coperWatcher.addTarget(customTarget);
|
coperWatcher.addTarget(customTarget);
|
||||||
|
|
||||||
coperWatcher.collect(
|
coperWatcher.collect(copyNodes, {}, true, collectorOptions.type);
|
||||||
copyNodes.map((node) => ({ id: `${node.id}`, name: `${node.name || node.id}` })),
|
|
||||||
{},
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
Object.keys(customTarget.deps).forEach((nodeId: Id) => {
|
Object.keys(customTarget.deps).forEach((nodeId: Id) => {
|
||||||
const node = editorService.getNodeById(nodeId);
|
const node = editorService.getNodeById(nodeId);
|
||||||
|
@ -20,7 +20,7 @@ import { reactive, toRaw } from 'vue';
|
|||||||
import { cloneDeep, get, isObject, mergeWith, uniq } from 'lodash-es';
|
import { cloneDeep, get, isObject, mergeWith, uniq } from 'lodash-es';
|
||||||
import { Writable } from 'type-fest';
|
import { Writable } from 'type-fest';
|
||||||
|
|
||||||
import { type CustomTargetOptions, Target, Watcher } from '@tmagic/dep';
|
import { Target, type TargetOptions, Watcher } from '@tmagic/dep';
|
||||||
import type { Id, MApp, MComponent, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema';
|
import type { Id, MApp, MComponent, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema';
|
||||||
import { NodeType } from '@tmagic/schema';
|
import { NodeType } from '@tmagic/schema';
|
||||||
import { calcValueByFontsize, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils';
|
import { calcValueByFontsize, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils';
|
||||||
@ -660,13 +660,12 @@ class Editor extends BaseService {
|
|||||||
* @param config 组件节点配置
|
* @param config 组件节点配置
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public copyWithRelated(config: MNode | MNode[], collectorOptions?: CustomTargetOptions): void {
|
public copyWithRelated(config: MNode | MNode[], collectorOptions?: TargetOptions): void {
|
||||||
const copyNodes: MNode[] = Array.isArray(config) ? config : [config];
|
const copyNodes: MNode[] = Array.isArray(config) ? config : [config];
|
||||||
|
|
||||||
// 初始化复制组件相关的依赖收集器
|
// 初始化复制组件相关的依赖收集器
|
||||||
if (collectorOptions && typeof collectorOptions.isTarget === 'function') {
|
if (collectorOptions && typeof collectorOptions.isTarget === 'function') {
|
||||||
const customTarget = new Target({
|
const customTarget = new Target({
|
||||||
id: 'related-comp-when-copy',
|
|
||||||
...collectorOptions,
|
...collectorOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -674,12 +673,7 @@ class Editor extends BaseService {
|
|||||||
|
|
||||||
coperWatcher.addTarget(customTarget);
|
coperWatcher.addTarget(customTarget);
|
||||||
|
|
||||||
coperWatcher.collect(
|
coperWatcher.collect(copyNodes, {}, true, collectorOptions.type);
|
||||||
copyNodes.map((node) => ({ id: `${node.id}`, name: `${node.name || node.id}` })),
|
|
||||||
{},
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
Object.keys(customTarget.deps).forEach((nodeId: Id) => {
|
Object.keys(customTarget.deps).forEach((nodeId: Id) => {
|
||||||
const node = this.getNodeById(nodeId);
|
const node = this.getNodeById(nodeId);
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
@ -706,10 +700,7 @@ class Editor extends BaseService {
|
|||||||
* @param position 粘贴的坐标
|
* @param position 粘贴的坐标
|
||||||
* @returns 添加后的组件节点配置
|
* @returns 添加后的组件节点配置
|
||||||
*/
|
*/
|
||||||
public async paste(
|
public async paste(position: PastePosition = {}, collectorOptions?: TargetOptions): Promise<MNode | MNode[] | void> {
|
||||||
position: PastePosition = {},
|
|
||||||
collectorOptions?: CustomTargetOptions,
|
|
||||||
): Promise<MNode | MNode[] | void> {
|
|
||||||
const config: MNode[] = storageService.getItem(COPY_STORAGE_KEY);
|
const config: MNode[] = storageService.getItem(COPY_STORAGE_KEY);
|
||||||
if (!Array.isArray(config)) return;
|
if (!Array.isArray(config)) return;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import { reactive } from 'vue';
|
|||||||
import { cloneDeep, mergeWith } from 'lodash-es';
|
import { cloneDeep, mergeWith } from 'lodash-es';
|
||||||
import { Writable } from 'type-fest';
|
import { Writable } from 'type-fest';
|
||||||
|
|
||||||
import { type CustomTargetOptions, Target, Watcher } from '@tmagic/dep';
|
import { Target, type TargetOptions, Watcher } from '@tmagic/dep';
|
||||||
import type { FormConfig } from '@tmagic/form';
|
import type { FormConfig } from '@tmagic/form';
|
||||||
import type { Id, MComponent, MNode } from '@tmagic/schema';
|
import type { Id, MComponent, MNode } from '@tmagic/schema';
|
||||||
import { getNodePath, getValueByKeyPath, guid, setValueByKeyPath, toLine } from '@tmagic/utils';
|
import { getNodePath, getValueByKeyPath, guid, setValueByKeyPath, toLine } from '@tmagic/utils';
|
||||||
@ -195,20 +195,19 @@ class Props extends BaseService {
|
|||||||
* @param originConfigs 原组件配置
|
* @param originConfigs 原组件配置
|
||||||
* @param targetConfigs 待替换的组件配置
|
* @param targetConfigs 待替换的组件配置
|
||||||
*/
|
*/
|
||||||
public replaceRelateId(originConfigs: MNode[], targetConfigs: MNode[], collectorOptions: CustomTargetOptions) {
|
public replaceRelateId(originConfigs: MNode[], targetConfigs: MNode[], collectorOptions: TargetOptions) {
|
||||||
const relateIdMap = this.getRelateIdMap();
|
const relateIdMap = this.getRelateIdMap();
|
||||||
|
|
||||||
if (Object.keys(relateIdMap).length === 0) return;
|
if (Object.keys(relateIdMap).length === 0) return;
|
||||||
|
|
||||||
const target = new Target({
|
const target = new Target({
|
||||||
id: 'related-comp-when-copy',
|
|
||||||
...collectorOptions,
|
...collectorOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
const coperWatcher = new Watcher();
|
const coperWatcher = new Watcher();
|
||||||
|
|
||||||
coperWatcher.addTarget(target);
|
coperWatcher.addTarget(target);
|
||||||
coperWatcher.collect(originConfigs);
|
coperWatcher.collect(originConfigs, {}, true, collectorOptions.type);
|
||||||
|
|
||||||
originConfigs.forEach((config: MNode) => {
|
originConfigs.forEach((config: MNode) => {
|
||||||
const newId = relateIdMap[config.id];
|
const newId = relateIdMap[config.id];
|
||||||
|
@ -104,7 +104,7 @@ const collectorOptions = {
|
|||||||
name: '蒙层',
|
name: '蒙层',
|
||||||
isTarget: (key: string | number, value: any) =>
|
isTarget: (key: string | number, value: any) =>
|
||||||
typeof key === 'string' && typeof value === 'string' && key.includes('events') && value.startsWith('overlay_'),
|
typeof key === 'string' && typeof value === 'string' && key.includes('events') && value.startsWith('overlay_'),
|
||||||
autoCollect: false,
|
isCollectByDefault: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const usePasteMenu = (menu?: Ref<InstanceType<typeof ContentMenu> | undefined>): MenuButton => ({
|
const usePasteMenu = (menu?: Ref<InstanceType<typeof ContentMenu> | undefined>): MenuButton => ({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user