mirror of
				https://github.com/Tencent/tmagic-editor.git
				synced 2025-11-04 02:28:04 +08:00 
			
		
		
		
	feat(editor): 支持代码块维度查看与组件的绑定关系,并支持从代码块列表解除绑定
This commit is contained in:
		
							parent
							
								
									5de3eeda71
								
							
						
					
					
						commit
						bfaa8317e3
					
				@ -65,7 +65,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
import { defineComponent, onUnmounted, PropType, provide, reactive, toRaw, watch } from 'vue';
 | 
					import { defineComponent, onUnmounted, PropType, provide, reactive, toRaw, watch } from 'vue';
 | 
				
			||||||
import { isEmpty } from 'lodash-es';
 | 
					import { isEmpty,union } from 'lodash-es';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { EventOption } from '@tmagic/core';
 | 
					import { EventOption } from '@tmagic/core';
 | 
				
			||||||
import type { FormConfig } from '@tmagic/form';
 | 
					import type { FormConfig } from '@tmagic/form';
 | 
				
			||||||
@ -210,6 +210,12 @@ export default defineComponent({
 | 
				
			|||||||
    updateDragEl: {
 | 
					    updateDragEl: {
 | 
				
			||||||
      type: Function as PropType<(el: HTMLDivElement, target: HTMLElement) => void>,
 | 
					      type: Function as PropType<(el: HTMLDivElement, target: HTMLElement) => void>,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** 可挂载代码块的生命周期 */
 | 
				
			||||||
 | 
					    codeHooks: {
 | 
				
			||||||
 | 
					      type: Array<string>,
 | 
				
			||||||
 | 
					      default: () => ['created', 'mounted'],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  emits: ['props-panel-mounted', 'update:modelValue'],
 | 
					  emits: ['props-panel-mounted', 'update:modelValue'],
 | 
				
			||||||
@ -230,8 +236,21 @@ export default defineComponent({
 | 
				
			|||||||
    const initCodeRelation = (rootValue: MNode) => {
 | 
					    const initCodeRelation = (rootValue: MNode) => {
 | 
				
			||||||
      if (isEmpty(rootValue.items)) return;
 | 
					      if (isEmpty(rootValue.items)) return;
 | 
				
			||||||
      rootValue.items.forEach((nodeValue: MNode) => {
 | 
					      rootValue.items.forEach((nodeValue: MNode) => {
 | 
				
			||||||
        if (!isEmpty(nodeValue.created)) {
 | 
					        let curNodeCombineIds:string[] = []
 | 
				
			||||||
          codeBlockService.setCompRelation(nodeValue.id, nodeValue.created);
 | 
					        // 合并各钩子绑定的代码块Id
 | 
				
			||||||
 | 
					        props.codeHooks.forEach((hook) => {
 | 
				
			||||||
 | 
					          // continue
 | 
				
			||||||
 | 
					          if (isEmpty(nodeValue[hook])) return true
 | 
				
			||||||
 | 
					          // 兼容单选绑定场景
 | 
				
			||||||
 | 
					          if(typeof nodeValue[hook] === 'string' && nodeValue[hook]) {
 | 
				
			||||||
 | 
					            curNodeCombineIds = union(curNodeCombineIds,[nodeValue[hook]])
 | 
				
			||||||
 | 
					          }else if(Array.isArray(nodeValue[hook])) {
 | 
				
			||||||
 | 
					            curNodeCombineIds = union(curNodeCombineIds,nodeValue[hook])
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        // 设置组件与代码块的绑定关系
 | 
				
			||||||
 | 
					        if(!isEmpty(curNodeCombineIds)) {
 | 
				
			||||||
 | 
					          codeBlockService.setCompRelation(nodeValue.id, curNodeCombineIds);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (!isEmpty(nodeValue.items)) {
 | 
					        if (!isEmpty(nodeValue.items)) {
 | 
				
			||||||
          initCodeRelation(nodeValue);
 | 
					          initCodeRelation(nodeValue);
 | 
				
			||||||
@ -351,6 +370,7 @@ export default defineComponent({
 | 
				
			|||||||
        containerHighlightType: props.containerHighlightType,
 | 
					        containerHighlightType: props.containerHighlightType,
 | 
				
			||||||
      }),
 | 
					      }),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					    provide('codeHooks',props.codeHooks)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return services;
 | 
					    return services;
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
				
			|||||||
@ -35,13 +35,14 @@
 | 
				
			|||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { computed, defineEmits, defineProps, inject, ref, watchEffect } from 'vue';
 | 
					import { computed, defineEmits, defineProps, inject, ref, watchEffect } from 'vue';
 | 
				
			||||||
import { ElMessage } from 'element-plus';
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
import { map } from 'lodash-es';
 | 
					import { map, union } from 'lodash-es';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { SelectConfig } from '@tmagic/form';
 | 
					import { SelectConfig } from '@tmagic/form';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { Services } from '../type';
 | 
					import type { Services } from '../type';
 | 
				
			||||||
import { EditorMode } from '../type';
 | 
					import { CodeEditorMode } from '../type';
 | 
				
			||||||
const services = inject<Services>('services');
 | 
					const services = inject<Services>('services');
 | 
				
			||||||
 | 
					const codeHooks = inject<string[]>('codeHooks');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const emit = defineEmits(['change']);
 | 
					const emit = defineEmits(['change']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,7 +80,6 @@ const fieldKey = ref('');
 | 
				
			|||||||
const combineIds = ref<string[]>([]);
 | 
					const combineIds = ref<string[]>([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
watchEffect(async () => {
 | 
					watchEffect(async () => {
 | 
				
			||||||
  if (!combineIds.value) return;
 | 
					 | 
				
			||||||
  const combineNames = await Promise.all(
 | 
					  const combineNames = await Promise.all(
 | 
				
			||||||
    combineIds.value.map(async (id) => {
 | 
					    combineIds.value.map(async (id) => {
 | 
				
			||||||
      const { name = '' } = (await services?.codeBlockService.getCodeContentById(id)) || {};
 | 
					      const { name = '' } = (await services?.codeBlockService.getCodeContentById(id)) || {};
 | 
				
			||||||
@ -90,20 +90,25 @@ watchEffect(async () => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const changeHandler = async (value: any) => {
 | 
					const changeHandler = async (value: any) => {
 | 
				
			||||||
  await setCombineRelation(value);
 | 
					  await setCombineRelation();
 | 
				
			||||||
  emit('change', value);
 | 
					  emit('change', value);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 同步绑定关系
 | 
					// 同步绑定关系
 | 
				
			||||||
const setCombineRelation = async (selectedIds: string[] | string) => {
 | 
					const setCombineRelation = async () => {
 | 
				
			||||||
  if (typeof selectedIds === 'string') {
 | 
					  //  绑定数组先置空
 | 
				
			||||||
    // 兼容select单选
 | 
					  combineIds.value = [];
 | 
				
			||||||
    combineIds.value = [selectedIds];
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    combineIds.value = selectedIds;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  // 组件id
 | 
					  // 组件id
 | 
				
			||||||
  const { id = '' } = services?.editorService.get('node') || {};
 | 
					  const { id = '' } = services?.editorService.get('node') || {};
 | 
				
			||||||
 | 
					  codeHooks?.forEach((hook) => {
 | 
				
			||||||
 | 
					    // continue
 | 
				
			||||||
 | 
					    if (!props.model[hook]) return true;
 | 
				
			||||||
 | 
					    if (typeof props.model[hook] === 'string' && props.model[hook]) {
 | 
				
			||||||
 | 
					      combineIds.value = union(combineIds.value, [props.model[hook]]);
 | 
				
			||||||
 | 
					    } else if (Array.isArray(props.model[hook])) {
 | 
				
			||||||
 | 
					      combineIds.value = union(combineIds.value, props.model[hook]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
  // 记录组件与代码块的绑定关系
 | 
					  // 记录组件与代码块的绑定关系
 | 
				
			||||||
  await services?.codeBlockService.setCompRelation(id, combineIds.value);
 | 
					  await services?.codeBlockService.setCompRelation(id, combineIds.value);
 | 
				
			||||||
  // 记录当前已被绑定的代码块,为查看弹窗的展示内容
 | 
					  // 记录当前已被绑定的代码块,为查看弹窗的展示内容
 | 
				
			||||||
@ -115,8 +120,8 @@ const viewHandler = async () => {
 | 
				
			|||||||
    ElMessage.error('请先绑定代码块');
 | 
					    ElMessage.error('请先绑定代码块');
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  await setCombineRelation(props.model[props.name]);
 | 
					  await setCombineRelation();
 | 
				
			||||||
  await services?.codeBlockService.setMode(EditorMode.LIST);
 | 
					  await services?.codeBlockService.setMode(CodeEditorMode.LIST);
 | 
				
			||||||
  services?.codeBlockService.setCodeEditorContent(true, combineIds.value[0]);
 | 
					  services?.codeBlockService.setCodeEditorContent(true, combineIds.value[0]);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@
 | 
				
			|||||||
  >
 | 
					  >
 | 
				
			||||||
    <layout v-model:left="left" :min-left="45" class="code-editor-layout">
 | 
					    <layout v-model:left="left" :min-left="45" class="code-editor-layout">
 | 
				
			||||||
      <!-- 左侧列表 -->
 | 
					      <!-- 左侧列表 -->
 | 
				
			||||||
      <template #left v-if="mode === EditorMode.LIST">
 | 
					      <template #left v-if="mode === CodeEditorMode.LIST">
 | 
				
			||||||
        <el-tree
 | 
					        <el-tree
 | 
				
			||||||
          v-if="!isEmpty(state.codeList)"
 | 
					          v-if="!isEmpty(state.codeList)"
 | 
				
			||||||
          ref="tree"
 | 
					          ref="tree"
 | 
				
			||||||
@ -35,7 +35,7 @@
 | 
				
			|||||||
        <div
 | 
					        <div
 | 
				
			||||||
          v-if="!isEmpty(codeConfig)"
 | 
					          v-if="!isEmpty(codeConfig)"
 | 
				
			||||||
          :class="[
 | 
					          :class="[
 | 
				
			||||||
            mode === EditorMode.LIST
 | 
					            mode === CodeEditorMode.LIST
 | 
				
			||||||
              ? 'm-editor-code-block-editor-panel-list-mode'
 | 
					              ? 'm-editor-code-block-editor-panel-list-mode'
 | 
				
			||||||
              : 'm-editor-code-block-editor-panel',
 | 
					              : 'm-editor-code-block-editor-panel',
 | 
				
			||||||
          ]"
 | 
					          ]"
 | 
				
			||||||
@ -82,7 +82,7 @@ import { ElMessage } from 'element-plus';
 | 
				
			|||||||
import { forIn, isEmpty } from 'lodash-es';
 | 
					import { forIn, isEmpty } from 'lodash-es';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import type { CodeBlockContent, CodeDslList, ListState, Services } from '../../../type';
 | 
					import type { CodeBlockContent, CodeDslList, ListState, Services } from '../../../type';
 | 
				
			||||||
import { EditorMode } from '../../../type';
 | 
					import { CodeEditorMode } from '../../../type';
 | 
				
			||||||
import MagicCodeEditor from '../../CodeEditor.vue';
 | 
					import MagicCodeEditor from '../../CodeEditor.vue';
 | 
				
			||||||
import Layout from '../../Layout.vue';
 | 
					import Layout from '../../Layout.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -132,7 +132,7 @@ const saveCode = async (): Promise<boolean> => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    // 代码内容
 | 
					    // 代码内容
 | 
				
			||||||
    const codeContent = codeEditor.value.getEditor().getValue();
 | 
					    const codeContent = codeEditor.value.getEditor()?.getValue();
 | 
				
			||||||
    /* eslint no-eval: "off" */
 | 
					    /* eslint no-eval: "off" */
 | 
				
			||||||
    codeConfig.value.content = eval(codeContent);
 | 
					    codeConfig.value.content = eval(codeContent);
 | 
				
			||||||
  } catch (e: any) {
 | 
					  } catch (e: any) {
 | 
				
			||||||
 | 
				
			|||||||
@ -25,21 +25,51 @@
 | 
				
			|||||||
      :data="state.codeList"
 | 
					      :data="state.codeList"
 | 
				
			||||||
      :highlight-current="true"
 | 
					      :highlight-current="true"
 | 
				
			||||||
      :filter-node-method="filterNode"
 | 
					      :filter-node-method="filterNode"
 | 
				
			||||||
 | 
					      @node-click="toggleCombineRelation"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <template #default="{ data }">
 | 
					      <template #default="{ data }">
 | 
				
			||||||
        <div :id="data.id" class="list-container">
 | 
					        <div :id="data.id" class="list-container">
 | 
				
			||||||
          <div class="list-item">
 | 
					          <div class="list-item">
 | 
				
			||||||
            <div class="code-name">{{ data.name }}({{ data.id }})</div>
 | 
					            <div class="code-name">{{ data.name }}({{ data.id }})</div>
 | 
				
			||||||
 | 
					            <!-- 右侧工具栏 -->
 | 
				
			||||||
            <div class="right-tool">
 | 
					            <div class="right-tool">
 | 
				
			||||||
              <el-tooltip effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
 | 
					              <el-tooltip effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
 | 
				
			||||||
                <Icon :icon="editable ? Edit : View" class="edit-icon" @click="editCode(`${data.id}`)"></Icon>
 | 
					                <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editCode(`${data.id}`)"></Icon>
 | 
				
			||||||
 | 
					              </el-tooltip>
 | 
				
			||||||
 | 
					              <el-tooltip
 | 
				
			||||||
 | 
					                effect="dark"
 | 
				
			||||||
 | 
					                content="查看绑定关系"
 | 
				
			||||||
 | 
					                placement="bottom"
 | 
				
			||||||
 | 
					                v-if="state.bindComps[data.id] && state.bindComps[data.id].length > 0"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <Icon :icon="Link" class="edit-icon" @click.stop="toggleCombineRelation(data)"></Icon>
 | 
				
			||||||
              </el-tooltip>
 | 
					              </el-tooltip>
 | 
				
			||||||
              <el-tooltip effect="dark" content="删除" placement="bottom" v-if="editable">
 | 
					              <el-tooltip effect="dark" content="删除" placement="bottom" v-if="editable">
 | 
				
			||||||
                <Icon :icon="Close" class="edit-icon" @click="deleteCode(`${data.id}`)"></Icon>
 | 
					                <Icon :icon="Close" class="edit-icon" @click.stop="deleteCode(`${data.id}`)"></Icon>
 | 
				
			||||||
              </el-tooltip>
 | 
					              </el-tooltip>
 | 
				
			||||||
              <slot name="code-block-panel-tool" :id="data.id"></slot>
 | 
					              <slot name="code-block-panel-tool" :id="data.id"></slot>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					          <!-- 展示代码块下绑定的组件 -->
 | 
				
			||||||
 | 
					          <div
 | 
				
			||||||
 | 
					            class="code-comp-map-wrapper"
 | 
				
			||||||
 | 
					            v-if="data.showRelation && state.bindComps[data.id] && state.bindComps[data.id].length > 0"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <svg class="arrow-left" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" data-v-029747aa="">
 | 
				
			||||||
 | 
					              <path
 | 
				
			||||||
 | 
					                fill="currentColor"
 | 
				
			||||||
 | 
					                d="M609.408 149.376 277.76 489.6a32 32 0 0 0 0 44.672l331.648 340.352a29.12 29.12 0 0 0 41.728 0 30.592 30.592 0 0 0 0-42.752L339.264 511.936l311.872-319.872a30.592 30.592 0 0 0 0-42.688 29.12 29.12 0 0 0-41.728 0z"
 | 
				
			||||||
 | 
					              ></path>
 | 
				
			||||||
 | 
					            </svg>
 | 
				
			||||||
 | 
					            <el-button
 | 
				
			||||||
 | 
					              v-for="(comp, index) in state.bindComps[data.id]"
 | 
				
			||||||
 | 
					              :key="index"
 | 
				
			||||||
 | 
					              class="code-comp"
 | 
				
			||||||
 | 
					              size="small"
 | 
				
			||||||
 | 
					              :plain="true"
 | 
				
			||||||
 | 
					              >{{ comp.name }}<Icon :icon="Close" class="comp-delete-icon" @click.stop="unbind(comp.id, data.id)"></Icon
 | 
				
			||||||
 | 
					            ></el-button>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
    </el-tree>
 | 
					    </el-tree>
 | 
				
			||||||
@ -54,41 +84,104 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { computed, inject, reactive, ref, watchEffect } from 'vue';
 | 
					import { computed, inject, reactive, ref, watch } from 'vue';
 | 
				
			||||||
import { Close, Edit, View } from '@element-plus/icons-vue';
 | 
					import { Close, Edit, Link, View } from '@element-plus/icons-vue';
 | 
				
			||||||
import { ElMessage } from 'element-plus';
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
import { flattenDeep, forIn, isEmpty, values } from 'lodash-es';
 | 
					import { flattenDeep, forIn, isEmpty, values, xor } from 'lodash-es';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Id } from '@tmagic/schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Icon from '../../../components/Icon.vue';
 | 
					import Icon from '../../../components/Icon.vue';
 | 
				
			||||||
import type { CodeBlockContent, Services } from '../../../type';
 | 
					import type { CodeBlockContent, Services } from '../../../type';
 | 
				
			||||||
import { CodeDslList, EditorMode, ErrorType, ListState } from '../../../type';
 | 
					import { CodeDeleteErrorType, CodeDslList, CodeEditorMode, ListState } from '../../../type';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import codeBlockEditor from './CodeBlockEditor.vue';
 | 
					import codeBlockEditor from './CodeBlockEditor.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps<{
 | 
					const props = defineProps<{
 | 
				
			||||||
  customError?: (id: string, errorType: ErrorType) => any;
 | 
					  customError?: (id: string, errorType: CodeDeleteErrorType) => any;
 | 
				
			||||||
}>();
 | 
					}>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const services = inject<Services>('services');
 | 
					const services = inject<Services>('services');
 | 
				
			||||||
 | 
					const codeHooks = inject<string[]>('codeHooks') || [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 代码块列表
 | 
					// 代码块列表
 | 
				
			||||||
const state = reactive<ListState>({
 | 
					const state = reactive<ListState>({
 | 
				
			||||||
  codeList: [],
 | 
					  codeList: [],
 | 
				
			||||||
 | 
					  bindComps: {},
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const editable = computed(() => services?.codeBlockService.getEditStatus());
 | 
					const editable = computed(() => services?.codeBlockService.getEditStatus());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
watchEffect(async () => {
 | 
					// 根据代码块ID获取其绑定的组件信息
 | 
				
			||||||
 | 
					const getBindCompsByCodeId = (codeId: string) => {
 | 
				
			||||||
 | 
					  const bindCompIds = services?.codeBlockService.getCodeRelationById(codeId) || [];
 | 
				
			||||||
 | 
					  if (isEmpty(bindCompIds)) {
 | 
				
			||||||
 | 
					    state.bindComps[codeId] = [];
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const compsInfo = bindCompIds.map((compId) => ({
 | 
				
			||||||
 | 
					    id: compId,
 | 
				
			||||||
 | 
					    name: getCompName(compId),
 | 
				
			||||||
 | 
					  }));
 | 
				
			||||||
 | 
					  state.bindComps[codeId] = compsInfo;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 初始化代码块列表
 | 
				
			||||||
 | 
					const initList = async () => {
 | 
				
			||||||
  const codeDsl = (await services?.codeBlockService.getCodeDsl()) || null;
 | 
					  const codeDsl = (await services?.codeBlockService.getCodeDsl()) || null;
 | 
				
			||||||
  if (!codeDsl) return;
 | 
					  if (!codeDsl) return;
 | 
				
			||||||
  state.codeList = [];
 | 
					  state.codeList = [];
 | 
				
			||||||
  forIn(codeDsl, (value: CodeBlockContent, key: string) => {
 | 
					  forIn(codeDsl, (value: CodeBlockContent, codeId: string) => {
 | 
				
			||||||
 | 
					    getBindCompsByCodeId(codeId);
 | 
				
			||||||
    state.codeList.push({
 | 
					    state.codeList.push({
 | 
				
			||||||
      id: key,
 | 
					      id: codeId,
 | 
				
			||||||
      name: value.name,
 | 
					      name: value.name,
 | 
				
			||||||
      content: value.content,
 | 
					      content: value.content,
 | 
				
			||||||
 | 
					      showRelation: false,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					  () => services?.codeBlockService.getCodeDsl(),
 | 
				
			||||||
 | 
					  () => {
 | 
				
			||||||
 | 
					    initList();
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    immediate: true,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 监听绑定关系修改,更新到代码块列表
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					  () => services?.codeBlockService.getCompRelation(),
 | 
				
			||||||
 | 
					  (curRelation, oldRelation) => {
 | 
				
			||||||
 | 
					    forIn(curRelation, (codeArr, compId) => {
 | 
				
			||||||
 | 
					      let oldCodeArr: string[] = [];
 | 
				
			||||||
 | 
					      if (oldRelation) {
 | 
				
			||||||
 | 
					        oldCodeArr = oldRelation[compId];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      // 可能一次清空全部绑定关系,对比结果为数组
 | 
				
			||||||
 | 
					      const diffCodeIds = xor(codeArr, oldCodeArr);
 | 
				
			||||||
 | 
					      diffCodeIds.forEach((codeId) => getBindCompsByCodeId(codeId));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 监听组件名称修改,更新到代码块列表
 | 
				
			||||||
 | 
					watch(
 | 
				
			||||||
 | 
					  () => services?.editorService.get('node'),
 | 
				
			||||||
 | 
					  (curNode) => {
 | 
				
			||||||
 | 
					    if (!curNode?.id) return;
 | 
				
			||||||
 | 
					    forIn(state.bindComps, (bindCompInfo) => {
 | 
				
			||||||
 | 
					      bindCompInfo.forEach((comp) => {
 | 
				
			||||||
 | 
					        if (comp.id === curNode.id) {
 | 
				
			||||||
 | 
					          comp.name = curNode.name;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 新增代码块
 | 
					// 新增代码块
 | 
				
			||||||
const createCodeBlock = async () => {
 | 
					const createCodeBlock = async () => {
 | 
				
			||||||
@ -101,7 +194,7 @@ const createCodeBlock = async () => {
 | 
				
			|||||||
    name: '代码块',
 | 
					    name: '代码块',
 | 
				
			||||||
    content: `() => {\n  // place your code here\n}`,
 | 
					    content: `() => {\n  // place your code here\n}`,
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  await codeBlockService.setMode(EditorMode.EDITOR);
 | 
					  await codeBlockService.setMode(CodeEditorMode.EDITOR);
 | 
				
			||||||
  const id = await codeBlockService.getUniqueId();
 | 
					  const id = await codeBlockService.getUniqueId();
 | 
				
			||||||
  await codeBlockService.setCodeDslById(id, codeConfig);
 | 
					  await codeBlockService.setCodeDslById(id, codeConfig);
 | 
				
			||||||
  codeBlockService.setCodeEditorContent(true, id);
 | 
					  codeBlockService.setCodeEditorContent(true, id);
 | 
				
			||||||
@ -109,7 +202,7 @@ const createCodeBlock = async () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 编辑代码块
 | 
					// 编辑代码块
 | 
				
			||||||
const editCode = async (key: string) => {
 | 
					const editCode = async (key: string) => {
 | 
				
			||||||
  await services?.codeBlockService.setMode(EditorMode.EDITOR);
 | 
					  await services?.codeBlockService.setMode(CodeEditorMode.EDITOR);
 | 
				
			||||||
  services?.codeBlockService.setCodeEditorContent(true, key);
 | 
					  services?.codeBlockService.setCodeEditorContent(true, key);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -123,7 +216,7 @@ const deleteCode = (key: string) => {
 | 
				
			|||||||
    services?.codeBlockService.deleteCodeDslByIds([key]);
 | 
					    services?.codeBlockService.deleteCodeDslByIds([key]);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    if (typeof props.customError === 'function') {
 | 
					    if (typeof props.customError === 'function') {
 | 
				
			||||||
      props.customError(key, codeIds.includes(key) ? ErrorType.BIND : ErrorType.UNDELETEABLE);
 | 
					      props.customError(key, codeIds.includes(key) ? CodeDeleteErrorType.BIND : CodeDeleteErrorType.UNDELETEABLE);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      ElMessage.error('代码块删除失败');
 | 
					      ElMessage.error('代码块删除失败');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -143,4 +236,28 @@ const filterNode = (value: string, data: CodeDslList): boolean => {
 | 
				
			|||||||
const filterTextChangeHandler = (val: string) => {
 | 
					const filterTextChangeHandler = (val: string) => {
 | 
				
			||||||
  tree.value?.filter(val);
 | 
					  tree.value?.filter(val);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 展示/隐藏组件绑定关系
 | 
				
			||||||
 | 
					const toggleCombineRelation = (data: CodeDslList) => {
 | 
				
			||||||
 | 
					  const { id } = data;
 | 
				
			||||||
 | 
					  const currentCode = state.codeList.find((item) => item.id === id);
 | 
				
			||||||
 | 
					  if (!currentCode) return;
 | 
				
			||||||
 | 
					  currentCode.showRelation = !currentCode?.showRelation;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 获取组件名称展示到tag上
 | 
				
			||||||
 | 
					const getCompName = (compId: Id): string => {
 | 
				
			||||||
 | 
					  const node = services?.editorService.getNodeById(compId);
 | 
				
			||||||
 | 
					  return node?.name || String(compId);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 解除绑定
 | 
				
			||||||
 | 
					const unbind = async (compId: Id, codeId: string) => {
 | 
				
			||||||
 | 
					  const res = await services?.codeBlockService.unbind(compId, codeId, codeHooks);
 | 
				
			||||||
 | 
					  if (res) {
 | 
				
			||||||
 | 
					    ElMessage.success('绑定关系解除成功');
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    ElMessage.error('绑定关系解除失败');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
@ -17,11 +17,13 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { reactive } from 'vue';
 | 
					import { reactive } from 'vue';
 | 
				
			||||||
import { keys, omit, pick } from 'lodash-es';
 | 
					import { forIn, isEmpty, keys, omit, pick } from 'lodash-es';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Id } from '@tmagic/schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import editorService from '../services/editor';
 | 
					import editorService from '../services/editor';
 | 
				
			||||||
import type { CodeBlockContent, CodeBlockDSL, CodeState, CompRelation } from '../type';
 | 
					import type { CodeBlockContent, CodeBlockDSL, CodeState, CompRelation } from '../type';
 | 
				
			||||||
import { EditorMode } from '../type';
 | 
					import { CodeEditorMode } from '../type';
 | 
				
			||||||
import { info } from '../utils/logger';
 | 
					import { info } from '../utils/logger';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import BaseService from './BaseService';
 | 
					import BaseService from './BaseService';
 | 
				
			||||||
@ -32,7 +34,7 @@ class CodeBlock extends BaseService {
 | 
				
			|||||||
    codeDsl: null,
 | 
					    codeDsl: null,
 | 
				
			||||||
    id: '',
 | 
					    id: '',
 | 
				
			||||||
    editable: true,
 | 
					    editable: true,
 | 
				
			||||||
    mode: EditorMode.EDITOR,
 | 
					    mode: CodeEditorMode.EDITOR,
 | 
				
			||||||
    combineIds: [],
 | 
					    combineIds: [],
 | 
				
			||||||
    compRelation: {},
 | 
					    compRelation: {},
 | 
				
			||||||
    undeletableList: [],
 | 
					    undeletableList: [],
 | 
				
			||||||
@ -191,18 +193,18 @@ class CodeBlock extends BaseService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * 获取当前模式
 | 
					   * 获取当前模式
 | 
				
			||||||
   * @returns {EditorMode}
 | 
					   * @returns {CodeEditorMode}
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public getMode(): EditorMode {
 | 
					  public getMode(): CodeEditorMode {
 | 
				
			||||||
    return this.state.mode;
 | 
					    return this.state.mode;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * 设置当前模式
 | 
					   * 设置当前模式
 | 
				
			||||||
   * @param {EditorMode} mode 模式
 | 
					   * @param {CodeEditorMode} mode 模式
 | 
				
			||||||
   * @returns {void}
 | 
					   * @returns {void}
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public async setMode(mode: EditorMode): Promise<void> {
 | 
					  public async setMode(mode: CodeEditorMode): Promise<void> {
 | 
				
			||||||
    this.state.mode = mode;
 | 
					    this.state.mode = mode;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -232,6 +234,7 @@ class CodeBlock extends BaseService {
 | 
				
			|||||||
  public async setCompRelation(compId: number | string, codeIds: string[]) {
 | 
					  public async setCompRelation(compId: number | string, codeIds: string[]) {
 | 
				
			||||||
    if (!compId) return;
 | 
					    if (!compId) return;
 | 
				
			||||||
    this.state.compRelation = {
 | 
					    this.state.compRelation = {
 | 
				
			||||||
 | 
					      ...this.state.compRelation,
 | 
				
			||||||
      [compId]: codeIds,
 | 
					      [compId]: codeIds,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -244,6 +247,22 @@ class CodeBlock extends BaseService {
 | 
				
			|||||||
    return this.state.compRelation;
 | 
					    return this.state.compRelation;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * 获取代码块与组件的绑定关系
 | 
				
			||||||
 | 
					   * @param {string} codeId 代码块id
 | 
				
			||||||
 | 
					   * @returns {Id[]} 该代码块绑定的组件id数组
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public getCodeRelationById(codeId: string): Id[] {
 | 
				
			||||||
 | 
					    const codeRelation = reactive<Id[]>([]);
 | 
				
			||||||
 | 
					    const compRelation = this.getCompRelation();
 | 
				
			||||||
 | 
					    forIn(compRelation, (value, key) => {
 | 
				
			||||||
 | 
					      if (value.includes(codeId)) {
 | 
				
			||||||
 | 
					        codeRelation.push(key);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return codeRelation;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * 获取不可删除列表
 | 
					   * 获取不可删除列表
 | 
				
			||||||
   * @returns {string[]}
 | 
					   * @returns {string[]}
 | 
				
			||||||
@ -286,12 +305,39 @@ class CodeBlock extends BaseService {
 | 
				
			|||||||
    return await this.getUniqueId();
 | 
					    return await this.getUniqueId();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * 一对一解除绑定关系
 | 
				
			||||||
 | 
					   * @param {string} compId 组件id
 | 
				
			||||||
 | 
					   * @param {string} codeId 代码块id
 | 
				
			||||||
 | 
					   * @param {string[]} codeHooks 代码块挂载hook名称
 | 
				
			||||||
 | 
					   * @returns {boolean} 结果
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  public async unbind(compId: Id, codeId: string, codeHooks: string[]): Promise<boolean> {
 | 
				
			||||||
 | 
					    const nodeInfo = editorService.getNodeById(compId);
 | 
				
			||||||
 | 
					    if (!nodeInfo) return false;
 | 
				
			||||||
 | 
					    // 更新node节点信息
 | 
				
			||||||
 | 
					    codeHooks.forEach((hook) => {
 | 
				
			||||||
 | 
					      if (!isEmpty(nodeInfo[hook])) {
 | 
				
			||||||
 | 
					        const newHookInfo = nodeInfo[hook].filter((item: string) => item !== codeId);
 | 
				
			||||||
 | 
					        nodeInfo[hook] = newHookInfo;
 | 
				
			||||||
 | 
					        editorService.update(nodeInfo);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    // 更新绑定关系
 | 
				
			||||||
 | 
					    const oldRelation = await this.getCompRelation();
 | 
				
			||||||
 | 
					    const oldCodeIds = oldRelation[compId];
 | 
				
			||||||
 | 
					    // 不能直接splice修改原数组,会导致绑定关系更新错乱
 | 
				
			||||||
 | 
					    const newCodeIds = oldCodeIds.filter((item) => item !== codeId);
 | 
				
			||||||
 | 
					    this.setCompRelation(compId, newCodeIds);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public destroy() {
 | 
					  public destroy() {
 | 
				
			||||||
    this.state.isShowCodeEditor = false;
 | 
					    this.state.isShowCodeEditor = false;
 | 
				
			||||||
    this.state.codeDsl = null;
 | 
					    this.state.codeDsl = null;
 | 
				
			||||||
    this.state.id = '';
 | 
					    this.state.id = '';
 | 
				
			||||||
    this.state.editable = true;
 | 
					    this.state.editable = true;
 | 
				
			||||||
    this.state.mode = EditorMode.EDITOR;
 | 
					    this.state.mode = CodeEditorMode.EDITOR;
 | 
				
			||||||
    this.state.combineIds = [];
 | 
					    this.state.combineIds = [];
 | 
				
			||||||
    this.state.compRelation = {};
 | 
					    this.state.compRelation = {};
 | 
				
			||||||
    this.state.undeletableList = [];
 | 
					    this.state.undeletableList = [];
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,8 @@
 | 
				
			|||||||
.m-editor-code-block-list {
 | 
					.m-editor-code-block-list {
 | 
				
			||||||
  margin-top: 5px;
 | 
					  margin-top: 5px;
 | 
				
			||||||
 | 
					  .el-tree-node__content {
 | 
				
			||||||
 | 
					    height: auto;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  .code-header-wrapper {
 | 
					  .code-header-wrapper {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
@ -47,6 +50,25 @@
 | 
				
			|||||||
        margin-right: 60px;
 | 
					        margin-right: 60px;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    .code-comp-map-wrapper {
 | 
				
			||||||
 | 
					      display: flex;
 | 
				
			||||||
 | 
					      align-items: center;
 | 
				
			||||||
 | 
					      flex-wrap: wrap;
 | 
				
			||||||
 | 
					      margin-left: 20px;
 | 
				
			||||||
 | 
					      margin-bottom: 5px;
 | 
				
			||||||
 | 
					      .arrow-left {
 | 
				
			||||||
 | 
					        transform: rotate(-45deg);
 | 
				
			||||||
 | 
					        width: 20px;
 | 
				
			||||||
 | 
					        height: 20px;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      .code-comp {
 | 
				
			||||||
 | 
					        margin-left: 5px;
 | 
				
			||||||
 | 
					        padding: 5px;
 | 
				
			||||||
 | 
					        .comp-delete-icon {
 | 
				
			||||||
 | 
					          margin-left: 3px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -329,7 +329,7 @@ export type CodeState = {
 | 
				
			|||||||
  /** 代码块是否可编辑 */
 | 
					  /** 代码块是否可编辑 */
 | 
				
			||||||
  editable: boolean;
 | 
					  editable: boolean;
 | 
				
			||||||
  /** 代码编辑面板的展示模式 */
 | 
					  /** 代码编辑面板的展示模式 */
 | 
				
			||||||
  mode: EditorMode;
 | 
					  mode: CodeEditorMode;
 | 
				
			||||||
  /** list模式下左侧展示的代码列表 */
 | 
					  /** list模式下左侧展示的代码列表 */
 | 
				
			||||||
  combineIds: string[];
 | 
					  combineIds: string[];
 | 
				
			||||||
  /** 组件和代码块的绑定关系 */
 | 
					  /** 组件和代码块的绑定关系 */
 | 
				
			||||||
@ -338,7 +338,7 @@ export type CodeState = {
 | 
				
			|||||||
  undeletableList: string[];
 | 
					  undeletableList: string[];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export enum EditorMode {
 | 
					export enum CodeEditorMode {
 | 
				
			||||||
  /** 左侧菜单,右侧代码 */
 | 
					  /** 左侧菜单,右侧代码 */
 | 
				
			||||||
  LIST = 'list',
 | 
					  LIST = 'list',
 | 
				
			||||||
  /** 全屏代码 */
 | 
					  /** 全屏代码 */
 | 
				
			||||||
@ -347,7 +347,7 @@ export enum EditorMode {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export type CompRelation = {
 | 
					export type CompRelation = {
 | 
				
			||||||
  /** 代码块绑定关系:组件id-代码块id数组 */
 | 
					  /** 代码块绑定关系:组件id-代码块id数组 */
 | 
				
			||||||
  [compId: string | number]: string[];
 | 
					  [compId: Id]: string[];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface CodeDslList {
 | 
					export interface CodeDslList {
 | 
				
			||||||
@ -357,13 +357,21 @@ export interface CodeDslList {
 | 
				
			|||||||
  name: string;
 | 
					  name: string;
 | 
				
			||||||
  /** 代码块函数内容 */
 | 
					  /** 代码块函数内容 */
 | 
				
			||||||
  content: any;
 | 
					  content: any;
 | 
				
			||||||
 | 
					  /** 是否展示代码绑定关系 */
 | 
				
			||||||
 | 
					  showRelation?: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface ListState {
 | 
					export interface ListState {
 | 
				
			||||||
  /** 代码块列表 */
 | 
					  /** 代码块列表 */
 | 
				
			||||||
  codeList: CodeDslList[];
 | 
					  codeList: CodeDslList[];
 | 
				
			||||||
 | 
					  /** 与代码块绑定的组件id信息 */
 | 
				
			||||||
 | 
					  bindComps: {
 | 
				
			||||||
 | 
					    /** 代码块id : 组件信息 */
 | 
				
			||||||
 | 
					    [id: string]: MNode[];
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export enum ErrorType {
 | 
					export enum CodeDeleteErrorType {
 | 
				
			||||||
  /** 代码块存在于不可删除列表中 */
 | 
					  /** 代码块存在于不可删除列表中 */
 | 
				
			||||||
  UNDELETEABLE = 'undeleteable',
 | 
					  UNDELETEABLE = 'undeleteable',
 | 
				
			||||||
  /** 代码块存在绑定关系 */
 | 
					  /** 代码块存在绑定关系 */
 | 
				
			||||||
 | 
				
			|||||||
@ -229,6 +229,12 @@ export const fillConfig = (config: FormConfig = []) => [
 | 
				
			|||||||
            type: 'code-select',
 | 
					            type: 'code-select',
 | 
				
			||||||
            labelWidth: '100px',
 | 
					            labelWidth: '100px',
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            name: 'mounted',
 | 
				
			||||||
 | 
					            text: 'mounted',
 | 
				
			||||||
 | 
					            type: 'code-select',
 | 
				
			||||||
 | 
					            labelWidth: '100px',
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
 | 
				
			|||||||
@ -26,6 +26,11 @@ export default {
 | 
				
			|||||||
      // eslint-disable-next-line no-eval
 | 
					      // eslint-disable-next-line no-eval
 | 
				
			||||||
      content: eval(`(vm) => {\n  console.log("this is getData function")\n}`),
 | 
					      content: eval(`(vm) => {\n  console.log("this is getData function")\n}`),
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    code_5316: {
 | 
				
			||||||
 | 
					      name: 'getList',
 | 
				
			||||||
 | 
					      // eslint-disable-next-line no-eval
 | 
				
			||||||
 | 
					      content: eval(`(vm) => {\n  console.log("this is getList function")\n}`),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  items: [
 | 
					  items: [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -51,7 +56,8 @@ export default {
 | 
				
			|||||||
        fontWeight: '',
 | 
					        fontWeight: '',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      events: [],
 | 
					      events: [],
 | 
				
			||||||
      created: ['code_5336'],
 | 
					      created: ['code_5316'],
 | 
				
			||||||
 | 
					      mounted: ['code_5336'],
 | 
				
			||||||
      items: [
 | 
					      items: [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          type: 'text',
 | 
					          type: 'text',
 | 
				
			||||||
@ -76,7 +82,7 @@ export default {
 | 
				
			|||||||
          text: 'Tmagic editor 营销活动编辑器',
 | 
					          text: 'Tmagic editor 营销活动编辑器',
 | 
				
			||||||
          multiple: true,
 | 
					          multiple: true,
 | 
				
			||||||
          events: [],
 | 
					          events: [],
 | 
				
			||||||
          created: [],
 | 
					          created: ['code_5316'],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          type: 'qrcode',
 | 
					          type: 'qrcode',
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user