当前位置: 首页 > news >正文

windows部署腾讯tmagic-editor02-Runtime

创建editor项目

将上一教程中的hello-world复制过来,改名hello-editor

创建runtime项目

和hello-editor同级

pnpm create vite

在这里插入图片描述
在这里插入图片描述
删除src/components/HelloWorld.vue

按钮需要用的ts types依赖

pnpm add @tmagic/schema @tmagic/stage

在这里插入图片描述

实现runtime

将hello-editor中的render函数实现移植到runtime项目中

<script setup lang="ts">
import {createApp,ref, computed} from 'vue';
import type StageCore from '@tmagic/stage';const value = ref({type: 'app',// 必须加上ID,这个id可能是数据库生成的key,也可以是生成的uuidid: 1,items: [],
});const render = async ({renderer}:StageCore) => {const root = window.document.createElement('div');const page = value.value.items[0];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;
};
</script><template><div></div>
</template><style scoped>
</style>

新建ui-page.vue文件

<template><div v-if="config" :id="config.id" :style="style"><div v-for="node in config.items" :key="node.id" :id="node.id">hello world</div></div>
</template><script lang="ts" setup>
import { computed } from 'vue';const props = defineProps<{config: any;
}>();const style = computed(() => {const { width = 375, height = 1700 } = props.config.style || {};return {width: `${width}px`,height: `${height}px`,};
});
</script>

将以下代码覆盖到src/App.vue中

<template><uiPage :config="page"></uiPage>
</template><script lang="ts" setup>
import { ref } from 'vue';import uiPage from './ui-page.vue';const page = ref<any>();
</script>

修改vite.config.js
在这里插入图片描述

启动项目
在这里插入图片描述

修改hello-editor

删除render props,添加runtimeUrl,修改样式app.vue

<template><m-editorv-model="value":runtime-url="runtimeUrl":component-group-list="componentGroupList"></m-editor>
</template><script lang="ts" setup>
import {ref, createApp, computed} from 'vue';
import {editorService} from '@tmagic/editor';const page = computed(() => editorService.get('page'));const value = ref({type: 'app',// 必须加上ID,这个id可能是数据库生成的key,也可以是生成的uuidid: 1,items: [],
});const componentGroupList = ref([{title: '组件列表',items: [{icon: 'https://vfiles.gtimg.cn/vupload/20220614/9cc3091655207317835.png',text: 'HelloWorld',type: 'hello-world',},],},
]);const runtimeUrl = 'http://localhost:8078/';
</script><style>
#app {overflow: auto;
}html,body,#app {height: 100%; margin: 0;padding: 0;
}#app::-webkit-scrollbar {width: 0 !important;display: none;
}
</style>

在这里插入图片描述
启动hello-editor
在这里插入图片描述

跨域问题

修改editor-runtime下的vite.config.js

 server: {port: 8078, //指定端口号headers:{'Access-Control-Allow-Origin': '*',}},

runtime与editor通信

到这里项目就可以正常访问了,但是会发现添加组件没有反应。

这是因为在runtime中无法直接获取到editor中的dsl,所以需要通过editor注入到window的magic api来交互

如出现在runtime中出现magic为undefined, 可以尝试在App.vue中通过监听message,来准备获取magic注入时机,然后调用magic.onRuntimeReady,示例代码如下

window.addEventListener('message', ({ data }) => {if (!data.tmagicRuntimeReady) {return;}window.magic?.onRuntimeReady({// ...});
});

注意:这里可能会出现editor抛出message的时候,runtime还没有执行到监听message的情况 编辑器只在iframe onload事件中抛出message 如果出现runtime中接收不到message的情况,可以尝试在onMounted的时候调用magic.onRuntimeReady

修改main.js为main.ts

import { createApp } from 'vue'
import type { Magic } from '@tmagic/stage';
import './style.css';
import App from './App.vue';declare global {interface Window {magic?: Magic;}
}
createApp(App).mount('#app')

新增tsconfig.json

{"compilerOptions": {"target": "esnext","module": "esnext","strict": true,"jsx": "preserve","moduleResolution": "node","skipLibCheck": true,"esModuleInterop": true,"allowSyntheticDefaultImports": true,"forceConsistentCasingInFileNames": true,"useDefineForClassFields": true,"sourceMap": true,"baseUrl": ".","types": ["webpack-env"],"paths": {"@/*": ["src/*"]},"lib": ["esnext","dom","dom.iterable","scripthost"]},"include": ["src/**/*.ts","src/**/*.tsx","src/**/*.vue","tests/**/*.ts","tests/**/*.tsx"],"exclude": ["node_modules"]
}

src下新增shims-vue.d.ts

/* eslint-disable */
declare module '*.vue' {import type { DefineComponent } from 'vue'const component: DefineComponent<{}, {}, any>export default component
}

修改runtime下的app.vue

<template><uiPage :config="page"></uiPage>
</template><script lang="ts" setup>
import type { RemoveData, UpdateData } from '@tmagic/stage';
import type { Id, MApp, MNode } from '@tmagic/schema';
import { ref,reactive } from 'vue';
import uiPage from './ui-page.vue';
const root = ref<MApp>();const page = ref<any>();window.magic?.onRuntimeReady({/** 当编辑器的dsl对象变化时会调用 */updateRootConfig(config: MApp) {root.value = config;},/** 当编辑器的切换页面时会调用 */updatePageId(id: Id) {page.value = root.value?.items?.find((item) => item.id === id);},/** 新增组件时调用 */add({ config }: UpdateData) {const parent = config.type === 'page' ? root.value : page.value;parent.items?.push(config);},/** 更新组件时调用 */update({ config }: UpdateData) {const index = page.value.items?.findIndex((child: MNode) => child.id === config.id);page.value.items.splice(index, 1, reactive(config));},/** 删除组件时调用 */remove({ id }: RemoveData) {const index = page.value.items?.findIndex((child: MNode) => child.id === id);page.value.items.splice(index, 1);},
});
</script>

同步页面dom给编辑器

由于组件渲染在runtime中,对于编辑器来说是个黑盒,并不知道哪个dom节点才是页面(对于dsl的解析渲染可能是千奇百怪的),所以需要将页面的dom节点同步给编辑器
修改runtime下的app.vue

const pageComp = ref<InstanceType<typeof uiPage>>();watch(page, async () => {// page配置变化后,需要等dom更新await nextTick();window?.magic?.onPageElUpdate(pageComp.value?.$el);
});

以上就是一个简单runtime实现,以及与编辑的交互,这是一个不完善的实现(会发现组件再画布中无法自由拖动,是因为没有完整的解析style),但是其中已经几乎覆盖所有需要关心的内容

当前教程中实现了一个简单的page,tmagic提供了一个比较完善的实现,将在下一节介绍

在这里插入图片描述

相关文章:

windows部署腾讯tmagic-editor02-Runtime

创建editor项目 将上一教程中的hello-world复制过来&#xff0c;改名hello-editor 创建runtime项目 和hello-editor同级 pnpm create vite删除src/components/HelloWorld.vue 按钮需要用的ts types依赖 pnpm add tmagic/schema tmagic/stage实现runtime 将hello-editor中…...

“分块”算法的基本要素及 build() 函数的构建细节

【“分块”算法知识点】 ● 分块是用线段树的分区思想改良的暴力法。代码比线段树简单。效率比普通暴力法高。分块适合求解 m=n=10^5 规模的问题,或 m*sqrt(n)≈10^7 的问题。其中,n 为元素个数,m 为操作次数。 ● “分块”算法的基本要素 (1)块的大小用 block 表示。通常…...

畅捷通TPlus keyEdit.aspx、KeyInfoList.aspx SQL注入漏洞复现

前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 一、产…...

Ubuntu22 下配置 Qt5 环境

1. Qt 简介 Qt5 中的新功能&#xff0c;可以看到各个版本的情况Whats New in Qt 5 | Qt 5.15 Qt 源文件网址Index of /archive/qt 2. 安装 Qt Creator cd 到安装包所在目录&#xff0c;进行软件安装。赋予可执行权限&#xff0c;加上 sudo 权限进入安装&#xff0c;这样会安…...

普通人也能创业!轻资产短视频带货项目,引领普通人实现创业梦想

在这个信息爆炸的时代&#xff0c;创业似乎成为了越来越多人的梦想。然而&#xff0c;传统的创业模式 keJ0277 往往伴随着高昂的资金投入和复杂的管理流程&#xff0c;让许多普通人望而却步。然而&#xff0c;现在有一种轻资产短视频带货项目正在悄然兴起&#xff0c;它以其低…...

【Maven】Nexus简单使用

1、安装配置介绍Nexus私服&#xff1a; 安装配置指路上一篇详细教程博客 【Maven】Nexus私服简介_下载安装_登录-CSDN博客 简单介绍原有仓库类型&#xff1a; proxy代理仓库&#xff1a;代理远程仓库&#xff0c;访问全球中央仓库或其他公共仓库&#xff0c;将资源存储在私…...

winform嵌入excel 设置父窗体分辨率不是100% 嵌入excel分辨率变成双倍大小

在WinForms应用程序中嵌入Excel时&#xff0c;遇到分辨率问题可能是由于DPI缩放导致的。Windows 10及更高版本默认启用了DPI缩放&#xff0c;以便在高分辨率显示器上显示更清晰的内容。这可能会导致嵌入的应用程序&#xff08;如Excel&#xff09;看起来变大或变小。 解决方案 …...

前端系列-4 promise与async/await与fetch/axios使用方式

背景&#xff1a; 本文介绍promise使用方式&#xff0c;以及以Promise为基础的async/await用法和fetch/axios使用方式&#xff0c;主要以案例的方式进行。 1.promise 1.1 promise介绍 javascript是单线程执行的&#xff0c;异步编程的本质是事件机制和函数回调。当执行阻塞…...

微信公众号自定义分销商城小程序源码系统 带完整的安装代码吧以及系统部署搭建教程

系统概述 微信公众号自定义分销商城小程序源码系统是一款功能强大的电商解决方案&#xff0c;它集成了商品管理、订单处理、支付接口、分销管理等多种功能。该系统支持自定义界面设计&#xff0c;商家可根据自身需求调整商城的页面布局和风格&#xff0c;打造独特的品牌形象。…...

在另外一个页面,让另外一个页面弹框显示操作(调佣公共的弹框)vue

大概意思是&#xff0c;登录弹框在另外一个页面中&#xff0c;而当前页面不存在&#xff0c;在当前页面中判断如果token不存在&#xff0c;就弹框出登录的弹框 最后一行 window.location.href … 如果当前用户已登录&#xff0c;则执行后续操作(注意此处&#xff0c;可不要)...

羊毛-百度Comate领50京东E卡

给你分享一个AI编码助手——百度Comate&#xff01;扫码参与抽红包活动&#xff0c;520宠粉&#xff01;送京东卡&#xff01;https://comate.baidu.com/?inviteCodeyysudp63 流程如下 点击&#xff1a;https://comate.baidu.com/?inviteCodeyysudp63添加链接描述 验证码…...

kafka安装部署

kafka 官网下载&#xff1a; kafka https://downloads.apache.org/kafka/3.7.0/zookeeper https://downloads.apache.org/zookeeper/ run kafkazookeeper&#xff0c;conf目录下创建zoo.cfg&#xff0c;运行bin目录下的zkServer脚本文件 kafka eagle 参考&#xff1a;htt…...

VBA直连SAP RFC 接口实例

引用依赖&#xff1a; VBA 调用 SAP API的RFC函数&#xff1a;RFC_READ_TABLE Sub A() 查询SAP表数据并输出到EXCEL&#xff0c;VBA中不区分大小写&#xff08;保存后会自动把代码、变量转换大小写&#xff09;Dim iData As Integer Dim nField As Integer Dim nData As Intege…...

2024如何挑选开放式蓝牙耳机?热门爆款熬夜整理六个点!

我以前也经常使用入耳式耳机&#xff0c;但总是会感觉耳机插在耳朵里不舒服&#xff0c;戴久了耳朵很疼&#xff0c;跑步的时候还总掉。还有在过马路的时候接电话、听音乐&#xff0c;几乎感知不到周围环境音&#xff0c;很不安全。而有了一款开放式蓝牙耳机后&#xff0c;就可…...

3D数据格式转换工具HOOPS Exchange在PLM系统中的5大应用优势

在当今竞争激烈的制造业环境中&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;系统已成为企业提升设计效率、缩短产品上市时间、降低成本和提高市场响应速度的关键工具。3D数据格式转换工具HOOPS Exchange&#xff0c;在PLM系统中扮演着至关重要的角色。以下是HOOPS …...

友元是一种允许某些外部函数或类访问另一个类的成员的机制

在C编程语言中&#xff0c;“友元”&#xff08;Friend&#xff09;是一种允许某些外部函数或类访问另一个类的私有&#xff08;private&#xff09;和保护&#xff08;protected&#xff09;成员的机制。友元功能在C中是非常有用的&#xff0c;尤其是在实现某些特定的功能时&a…...

儿童护眼台灯哪个牌子好,适合儿童使用的护眼台灯推荐

护眼台灯在近几年成为家长和经常与电子设备打交道的人士中备受瞩目的家用电器。对于有孩子的家庭而言&#xff0c;它几乎成为了必备品&#xff0c;许多消费者已经对其有了一定的了解并进行了购买。然而&#xff0c;仍有部分家长对护眼台灯的效果和重要性缺乏充分认识&#xff0…...

在电脑本地运行llama3-8b模型

文章目录 流程我的案例api调用llama.cpp 流程 ollama支持可运行的模型,图片这里只是一部分而已,只需要下载下面的软件和模型文件,即可直接运行,而无需配置其他 模型文件下载地址 https://ollama.com/library 支持的部分模型,实际上更多,这里只是显示部分 登陆ollama官网 htt…...

深入理解 House of Cat

Index 序言利用 FSOP 调用 House of Cat利用条件伪造IO流条件完整调用链分析 模板System (one_gadget) 模板ORW模板 Demo & Exp利用 __malloc_assert 调用 House of Cat例题&#xff1a;题目思路Exp 序言 原文章&#xff1a;深入理解 House of Cat 随着 GNU 持续不断的更…...

【Linux玩物志】Linux环境开发基本工具使用(1)——vim

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; Linux开发工具 首先我们要知道vim是什么&#xff1f; vi&#xff08;Visual Editor&#xff09;是由美国程序员比尔乌尔曼&#xff08;Bill Joy&#xff09;于1976年开发的&#xff0c;最初是为了在Unix系统上进行文本编…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...