windows部署腾讯tmagic-editor01-Hello world

之前写过一篇使用yarn实现的https://blog.csdn.net/qq_36437991/article/details/133644558,后面的两个没有写,这次准备重新实现

环境

pnpm 8.15.1

node 18.19.0

创建vue项目

bash 复制代码
pnpm create vite

cd hello-world
pnpm install

执行pnpm dev启动项目

安装依赖包

bash 复制代码
pnpm add @tmagic/editor @tmagic/form @tmagic/stage @tmagic/design @tmagic/element-plus-adapter element-plus

修改代码

注册组件

修改main.js

js 复制代码
import 'element-plus/dist/index.css';
import '@tmagic/editor/dist/style.css';
import '@tmagic/form/dist/style.css';

import { createApp } from 'vue';
import ElementPlus from 'element-plus';

import TMagicDesign from '@tmagic/design';
import TMagicEditor from '@tmagic/editor';
import TMagicElementPlusAdapter from '@tmagic/element-plus-adapter';
import TMagicForm from '@tmagic/form';

import App from './App.vue';

createApp(App)
    .use(ElementPlus)
    .use(TMagicDesign, TMagicElementPlusAdapter)
    .use(TMagicEditor)
    .use(TMagicForm)
    .mount('#app');

渲染编辑器

修改app.vue

html 复制代码
<template>
  <m-editor
      v-model="value"
      :render="render"
      :component-group-list="componentGroupList"
  ></m-editor>
</template>

<script lang="ts" setup>
import { ref } from 'vue';

const value = ref();

const componentGroupList = ref([]);

const render = () => window.document.createElement('div');
</script>

<style>
html,
body,
#app,
.m-editor {
  height: 100vh;
}

body {
  margin: 0;
}
</style>

删除components文件夹,pnpm dev启动项目报错

修改vite.config.js

js 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  optimizeDeps: {
    esbuildOptions: {
      define: {
        global: 'globalThis',
      },
    },
  },
})

重新启动项目不在报错

到这里一个空白的编辑器就运行起来了

添加组件列表

修改componentGroupList

js 复制代码
const componentGroupList = ref([
  {
    title: '组件列表',
    items: [
      {
        icon: 'https://vfiles.gtimg.cn/vupload/20220614/9cc3091655207317835.png',
        text: 'HelloWorld',
        type: 'hello-world',
      },
    ],
  },
]);

到这里,左侧会出现一个叫HelloWorld的爱心图标,点击它会发现没有反应,打开控制台会发现有error;这是因为还没有创建页面

点击中间的新增页面也会发现没有反应,这是因为没有编辑器初始值,只需要给value赋上初始值就可以了

设置编辑器初始值

修改value

js 复制代码
const value = ref({
  type: 'app',
  // 必须加上ID,这个id可能是数据库生成的key,也可以是生成的uuid
  id: 1,
  items: [],
});

加上初始值后,点击新增页面就可以渲染出一个画布了,但是点击添加HelloWorld组件依然没有反应

这是因为这时的编辑器并能理解HelloWorld是什么,需要在render函数中处理

渲染

修改render

js 复制代码
const render = () => {
  const root = window.document.createElement('div');
  const page = value.value.items[0];

  if (!page) return root;

  root.id = `${page.value.id}`;

  createApp(
    {
      template: '<p v-for="node in config.items" :key="node.id" :id="node.id">hello world</p>',
      props: ['config'],
    },
    {
      config: page,
    },
  ).mount(root);

  return root;
};

这里用到了动态编译Vue模板,所以需要在vue.config.js中添加vue alias,因为用的vite,所以需要修改vite.config.js

js 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve:{
    alias: {
      // 在 Vite 中,你不需要使用 `$` 来指定默认导出
      // 直接使用 'vue' 作为别名即可
      vue: 'vue/dist/vue.esm-bundler.js'
    }
  },
  optimizeDeps: {
    esbuildOptions: {
      define: {
        global: 'globalThis',
      },
    },
  },
})

render函数中获取page是通过value.value.items[0],这样只是表示第一个页面,如果页面有多个页面就会有问题 可以通过editorService.get('page')获取到当前选中的页面

js 复制代码
import { ref,createApp,computed } from 'vue';
import { editorService } from '@tmagic/editor';

const page = computed(() => editorService.get('page'));

到这已经能渲染出HelloWorld组件了,但是会发现无法选中,因为这时并不知道画布中的Dom已经发生变化,所以需要通知编辑器,需要调用

js 复制代码
renderer.iframe.contentWindow.magic?.onRuntimeReady({});
renderer.iframe.contentWindow.magic?.onPageElUpdate(root);

最终完整的render函数实现

js 复制代码
import type StageCore from '@tmagic/stage';

const render = async ({ renderer }: StageCore) => {
  const root = window.document.createElement('div');

  if (!page.value) return root;

  const { width = 375, height = 1700 } = page.value.style || {};

  root.id = `${page.value.id}`;
  root.style.cssText = `
    width: ${width}px;
    height: ${height}px;
  `;

  createApp(
    {
      template: '<div v-for="node in config.items" :key="node.id" :id="node.id">hello world</div>',
      props: ['config'],
    },
    {
      config: page.value,
    },
  ).mount(root);

  renderer.on('onload', () => {
    const style = window.document.createElement('style');
    // 隐藏滚动条,重置默认样式
    style.innerHTML = `
      body {
        overflow: auto;
      }

      html,body {
        height: 100%; margin: 0;padding: 0;
      }
      
      html::-webkit-scrollbar {
        width: 0 !important;
        display: none;
      }
    `;

    renderer.iframe?.contentDocument?.head.appendChild(style);

    renderer.contentWindow?.magic?.onPageElUpdate(root);
    renderer.contentWindow?.magic?.onRuntimeReady({});
  });

  return root;
};

以上就是一个简单的搭建编辑器的示例,安装上面的步骤完成后会发现,可以添加组件,也可选中组件,但是无法拖动,配置属性中的样式也无法生效,这是因为上述的render函数并不完整,没有处理dsl中style,下一节将详细介绍runtime的搭建,将不再使用render函数的方式而是使用runtimeUrl。

并不是render函数不好,但是从设计上将,render函数还是让渲染逻辑落到了编辑器中,@tmagic/editor的设计是希望做到渲染跟编辑器解耦

相关推荐
武藤一雄4 小时前
C# 关于多线程如何实现需要注意的问题(持续更新)
windows·后端·microsoft·c#·.net·.netcore·死锁
coding消烦员7 小时前
在 Windows 内网搭建 Git 仓库:共享普通仓库 vs 中心 bare 仓库
windows·git
xiaoliuliu1234512 小时前
IE8-WindowsXP-x86-CHS_23253_BDdl.exe 安装步骤(XP 32位简体中文版)
windows
百事牛科技12 小时前
文件不想再加密了?取消Word 打开密码的方法
windows·word
love530love13 小时前
EPGF 新手教程 13在 PyCharm(中文版 GUI)中创建 Hatch 项目环境,并把 Hatch 做成“项目自包含”(工具本地化为必做环节)
开发语言·ide·人工智能·windows·python·pycharm·hatch
峰上踏雪14 小时前
Go(Golang)Windows 环境配置关键点总结
开发语言·windows·golang·go语言
lusasky14 小时前
在Windows上编译、安装Rust
开发语言·windows·rust
麻辣长颈鹿Sir15 小时前
CMAKE指令集
linux·运维·windows·cmake·cmake指令集
Alice102915 小时前
如何在windows本地打包python镜像
开发语言·windows·python
北京流年15 小时前
windows安装jenkins并且编译app
运维·windows·jenkins