在vue3中使用tmagic-editor
在vue3中使用tmagic-editor引言重要概念具体实现tmagic-editor安装runtime项目搭建添加组件可能出现的问题注意事项引言腾讯开源的tmagic-editor是一款功能强大的可视化页面编辑器但需要注意的是它并非一个开箱即用的解决方案。在实际项目集成过程中开发者需要投入一定精力进行配置和开发工作。本文将简要介绍如何将tmagic-editor有效地集成到您的项目中。重要概念组件组件是构建页面的最小可操作单元在编辑器中通过组合和堆叠多个组件完成页面设计。每个组件具备独立的属性、样式和行为。runtimeruntime是动态响应编辑器操作的执行环境通常以iframe形式嵌入页面确保编辑效果实时预览。在代码层面需独立创建runtime项目负责解析组件配置、处理数据绑定及渲染逻辑。DSLDSL是描述页面结构和组件属性的结构化数据由编辑器生成。组件v-model所对应的值具体实现tmagic-editor安装首先确保你的node.js18,然后下载npm包npminstalltmagic/editor如果项目中使用了如 Element Plus 等 UI 组件库要下载对应的适配器npminstalltmagic/element-plus-adapter如果项目中没有 Monaco Editor也需要安装npminstallmonaco-editor在 main.js 中引入importeditorPluginfromtmagic/editor;importMagicElementPlusAdapterfromtmagic/element-plus-adapter;importtmagic/editor/dist/style.css;......app.use(editorPlugin,MagicElementPlusAdapter);最后创建editor.vue//editor.vuetemplatem-editor v-modeldsl:menumenu:runtime-urlruntimeUrl:props-configspropsConfigs:props-valuespropsValues:component-group-listcomponentGroupList/m-editor/templatescript setupimport{ref}fromvue;constdslref({type:app,id:1,items:[]});constmenuref({left:[// 顶部左侧菜单按钮],center:[// 顶部中间菜单按钮],right:[// 顶部右侧菜单按钮],});construntimeUrl/runtime/vue3/playground/index.html;constcomponentGroupListref([// 组件列表]);constpropsConfigsref([]);constpropsValuesref([]);/scriptruntime项目搭建官方在git源码中提供了不同框架的runtime项目样例我们可以直接复制过来使用。这里以vue3为例我们在自己的主项目根目录下创建一个runtime文件夹将源码中runtime/vue3文件夹粘贴到主项目的runtime下记得安装一下依赖。接下来我们修改一下runtime项目build.vite.config.ts中我们要修改bulid.outDir文件打包路径,base(公共基础路径。// build.vite.config.tsimportpathfrompath;import{defineConfig}fromvite;importlegacyfromvitejs/plugin-legacy;importvuefromvitejs/plugin-vue;importvueJsxfromvitejs/plugin-vue-jsx;// ts-ignoreimportexternalGlobalsfromrollup-plugin-external-globals;constINVALID_CHAR_REGEX/[\x00-\x1F\x7F*#{}|^[\];?:$,]/g;constDRIVE_LETTER_REGEX/^[a-z]:/i;exportdefaultdefineConfig(({mode}){if([value,config,event,ds:value,ds:config,ds:event].includes(mode)){constcapitalTokenmode.split(:).map((word)word[0].toUpperCase()word.slice(1)).join();constfileNamemode.replace(:,-);return{publicDir:./.tmagic/public,build:{cssCodeSplit:false,sourcemap:true,minify:false,target:esnext,outDir:../../public/entry/vue3/${fileName},// 修改项使文件输出到主项目的 public 下lib:{entry:.tmagic/${fileName}-entry.ts,name:magicPreset${capitalToken}s,fileName:index,formats:[umd],},},};}if([page,playground].includes(mode)){return{plugins:[vue(),vueJsx(),externalGlobals({vue-demi:VueDemi,vue:Vue},{exclude:[./${mode}/index.html]}),legacy({targets:[defaults,not IE 11],}),],root:./${mode}/,publicDir:../public,base:/runtime/vue3/${mode},// 修改项要与 editor.vue 中的 runtimeUrl 对应optimizeDeps:{exclude:[vue-demi],},build:{emptyOutDir:true,sourcemap:true,outDir:path.resolve(process.cwd(),../../public/runtime/vue3/${mode}),// 修改项使文件输出到主项目的 public 下rollupOptions:{external:[vue,vue-demi],output:{// https://github.com/rollup/rollup/blob/master/src/utils/sanitizeFileName.tssanitizeFileName(name){constmatchDRIVE_LETTER_REGEX.exec(name);constdriveLettermatch?match[0]:;returndriveLettername.slice(driveLetter.length).replace(INVALID_CHAR_REGEX,);},},},},};}return{};});dev.vite.config.ts中的base也要修改另外如果你没有别名的需求可以把resolve.alias也删了//dev.vite.config.tsimport{defineConfig}fromvite;importvuefromvitejs/plugin-vue;importvueJsxfromvitejs/plugin-vue-jsx;exportdefaultdefineConfig({plugins:[vue(),vueJsx()],root:./,base:/runtime/vue3/,//修改项publicDir:public,optimizeDeps:{exclude:[vue-demi],},server:{host:0.0.0.0,port:8078,strictPort:true,},});有些小伙伴已经注意到主项目和runtime项目是不同端口的两个独立项目那么主项目访问runtime项目是需要设置代理的我们在主项目的vite.config.ts中设置一下server:{port:4000,proxy:{// 选项写法/runtime/vue3/:{target:http://localhost:8078,changeOrigin:true}}}这时我们启动runtime项目在编辑器页面新建一个页面发现我们还无法在空白的页面中创作因为我们还缺少构建页面的基础——组件添加组件想要实现一个组件必须要有四个文件- index 入口文件- formConfig 表单配置- initValue 表单配置初始值- component.vue 组件代码现在我们在runtime项目根目录下添加一个test-component目录在目录中添加这四个文件// index.js// vueimportIndexfrom./Index.vue;export{defaultasconfig}from./formConfig;export{defaultasvalue}from./initValue;exportdefaultIndex;// formConfig.jsexportdefault[{type:select,text:字体颜色,name:color,options:[{text:红色字体,value:red,},{text:蓝色字体,value:blue,},],},{name:text,text:配置文案,},];// initValue.jsexportdefault{color:red,text:一段文字,};!--Index.vue--templatedivspanthisis a Test component:/spanspan:style{ color: config.color }{{config.text}}/span/div/templatescriptexportdefault{name:magic-ui-test,props:{config:{type:Object,default:()({}),},},setup(){},};/script然后我们要在runtime项目tmagic.config.ts中注册组件exportdefaultdefineConfig({packages:[{test:../../runtime/vue3/test-component},tmagic/ui],//数组中第一个就是我们刚写的组件后面是官方提供的组件我们也注册下方便后面使用。componentFileAffix:.vue,dynamicImport:true,});runtime项目中执行npm run build:libs执行完后就能在主项目的public下看到entry/vue3这么一个文件夹里面包含着有我们组件信息的文件。最后我们在editor.vue中配置我们要展示的组件templatem-editor v-modeldsl:menumenu:runtime-urlruntimeUrl:props-configspropsConfigs:props-valuespropsValues:component-group-listcomponentGroupList/m-editor/templatescript setupimport{ref}fromvue;import{asyncLoadJs}fromtmagic/editor;constdslref({type:app,id:1,items:[]});constmenuref({left:[// 顶部左侧菜单按钮],center:[// 顶部中间菜单按钮],right:[// 顶部右侧菜单按钮],});construntimeUrl/runtime/vue3/playground/index.html;constcomponentGroupListref([// 组件列表{title:基础组件,items:[{text:测试,type:test,},],},]);constpropsConfigsref([]);constpropsValuesref([]);//获取组件配置列表asyncLoadJs(/public/entry/vue3/config/index.umd.cjs).then((){propsConfigs.valueglobalThis.magicPresetConfigs;});//获取组件配置默认值asyncLoadJs(/public/entry/vue3/value/index.umd.cjs).then((){propsValues.valueglobalThis.magicPresetValues;});/script此刻页面的左面板已经出现了我们自己的test组件将test组件拖入中间工作区右面板就会出现相应的配置项了。到了这里你已经成功在本地搭建tmagic-editor的使用环境并实现了一个最简单的自定义组件。如果还想了解更多请前往官方文档可能出现的问题安装tmagic-editor后可能提示缺少sass或sass-embed依赖,安装对应依赖即可出现Uncaught ReferenceError: global is not defined在主项目vite.config.ts添加optimizeDeps:{esbuildOptions:{define:{global:globalThis,},},},注意事项刚查阅官方文档发现tmagic-editor的安装使用已做优化具体请以官方文档为准