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的设计是希望做到渲染跟编辑器解耦

相关推荐
搏博7 小时前
基于Python3.10.6与jieba库的中文分词模型接口在Windows Server 2022上的实现与部署教程
windows·python·自然语言处理·flask·中文分词
有梦想的攻城狮15 小时前
Java 11中的Collections类详解
java·windows·python·java11·collections
忒可君15 小时前
C# winform FTP功能
开发语言·windows·c#
十五年专注C++开发16 小时前
CMake进阶: CMake Modules---简化CMake配置的利器
linux·c++·windows·cmake·自动化构建
degree52016 小时前
全平台轻量浏览器推荐|支持Win/macOS/Linux,极速加载+隐私保护+扩展插件,告别广告与数据追踪!
windows·macos·电脑
许泽宇的技术分享2 天前
Windows桌面自动化的革命性突破:深度解析Windows-MCP.Net Desktop模块的技术奥秘
windows·自动化·.net
七仔的博客2 天前
【摸鱼办公神器】七仔的桌面工具超进化 -> 灵卡面板 v1.1.9
windows·神器·摸鱼
码农阿豪2 天前
Windows从零到一安装KingbaseES数据库及使用ksql工具连接全指南
数据库·windows
CC__xy2 天前
demo 通讯录 + 城市选择器 (字母索引左右联动 ListItemGroup+AlphabetIndexer)笔记
windows
LZQqqqqo3 天前
C# 中 ArrayList动态数组、List<T>列表与 Dictionary<T Key, T Value>字典的深度对比
windows·c#·list