2026-10-19 11:33:16 +00:00

75 lines
50 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>DSL SDK(@tmagic/editor/sdk) | tmagic-editor</title>
<meta name="description" content="页面可视化平台">
<meta name="generator" content="VitePress v2.0.0-alpha.20">
<link rel="preload stylesheet" href="/tmagic-editor/docs/assets/style.xjqBjHKn.css" as="style">
<link rel="preload stylesheet" href="/tmagic-editor/docs/assets/vp-icons.139f4833.css" as="style">
<script type="module" src="/tmagic-editor/docs/assets/chunks/metadata.90e584c8.js"></script>
<script type="module" src="/tmagic-editor/docs/assets/app.ek4dLOl2.js"></script>
<link rel="preload" href="/tmagic-editor/docs/assets/inter-roman-latin.q5rAVC0E.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/tmagic-editor/docs/assets/chunks/theme.CGxorDDM.js">
<link rel="modulepreload" href="/tmagic-editor/docs/assets/chunks/framework.DDIL1KmX.js">
<link rel="modulepreload" href="/tmagic-editor/docs/assets/api_editor_sdk.md.BZi1pwHS.lean.js">
<meta name="theme-color" content="#646cff">
<script id="check-dark-mode">(()=>{let e=localStorage.getItem(`vitepress-theme-appearance`)||`auto`,t=window.matchMedia(`(prefers-color-scheme: dark)`).matches;(!e||e===`auto`?t:e===`dark`)&&document.documentElement.classList.add(`dark`)})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle(`mac`,/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-440dbbdf><!--[--><!--]--><!--[--><span tabindex="-1" data-v-c779725a></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-c779725a>Skip to content</a><!--]--><!----><header class="VPNav" data-v-440dbbdf data-v-156bfb0e><div class="VPNavBar has-sidebar top" data-v-156bfb0e data-v-5d7186a2><div class="wrapper" data-v-5d7186a2><div class="container" data-v-5d7186a2><div class="title" data-v-5d7186a2><div class="VPNavBarTitle has-sidebar" data-v-5d7186a2 data-v-510de9a3><a class="title" href="/tmagic-editor/docs/" title="tmagic-editor" data-v-510de9a3><!--[--><!--]--><!--[--><img class="VPImage logo" src="./favicon.png" alt data-v-784e8c02><!--]--><span data-v-510de9a3>tmagic-editor</span><!--[--><!--]--></a></div></div><div class="content" data-v-5d7186a2><div class="content-body" data-v-5d7186a2><!--[--><!--]--><div class="VPNavBarSearch search" data-v-5d7186a2 data-v-4b977777><!--[--><button type="button" class="VPNavBarSearchButton" aria-label="Search" aria-keyshortcuts="/ control+k meta+k" data-v-4b977777 data-v-75cee97a><span class="vpi-search" aria-hidden="true" data-v-75cee97a></span><span class="text" data-v-75cee97a>Search</span><span class="keys" aria-hidden="true" data-v-75cee97a><kbd class="key-mod" data-v-75cee97a></kbd><kbd class="key-k" data-v-75cee97a></kbd></span></button><!----><!--]--></div><nav aria-label="Main Navigation" class="VPNavMenu VPNavBarMenu menu" data-v-5d7186a2 data-v-1a26812e><ul class="list" data-v-1a26812e><!--[--><li class="" data-v-1a26812e><a class="VPLink link VPNavMenuLink VPNavBarMenuLink" href="/tmagic-editor/docs/guide/" data-v-1a26812e data-v-cb5ee893><!--[--><span data-v-cb5ee893>文档</span><!--]--></a></li><li class="" data-v-1a26812e><a class="VPLink link VPNavMenuLink VPNavBarMenuLink active" href="/tmagic-editor/docs/api/editor/props.html" data-v-1a26812e data-v-cb5ee893><!--[--><span data-v-cb5ee893>Editor API</span><!--]--></a></li><li class="" data-v-1a26812e><a class="VPLink link VPNavMenuLink VPNavBarMenuLink" href="/tmagic-editor/docs/runtime-api/core/app.html" data-v-1a26812e data-v-cb5ee893><!--[--><span data-v-cb5ee893>Runtime API</span><!--]--></a></li><li class="" data-v-1a26812e><a class="VPLink link VPNavMenuLink VPNavBarMenuLink" href="/tmagic-editor/docs/form-config/fields/text.html" data-v-1a26812e data-v-cb5ee893><!--[--><span data-v-cb5ee893>表单配置</span><!--]--></a></li><li class="" data-v-1a26812e><a class="VPLink link vp-external-link-icon VPNavMenuLink VPNavBarMenuLink" href="https://github.com/Tencent/tmagic-editor/releases" target="_blank" rel="noreferrer" data-v-1a26812e data-v-cb5ee893><!--[--><span data-v-cb5ee893>更新日志</span><!--]--></a></li><li class="" data-v-1a26812e><a class="VPLink link vp-external-link-icon VPNavMenuLink VPNavBarMenuLink" href="https://tencent.github.io/tmagic-editor/playground/index.html" target="_blank" rel="noreferrer" data-v-1a26812e data-v-cb5ee893><!--[--><span data-v-cb5ee893>Playground</span><!--]--></a></li><!--]--></ul></nav><!----><div class="VPNavAppearance VPNavBarAppearance appearance" data-v-5d7186a2 data-v-680326c7><!----><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-label="Appearance" aria-checked="false" data-v-680326c7 data-v-ca894290 data-v-ef764d20><span class="check" data-v-ef764d20><span class="icon" data-v-ef764d20><!--[--><span class="vpi-sun sun" aria-hidden="true" data-v-ca894290></span><span class="vpi-moon moon" aria-hidden="true" data-v-ca894290></span><!--]--></span></span></button></div><ul class="VPSocialLinks VPNavSocialLinks VPNavBarSocialLinks social-links" data-v-5d7186a2 data-v-84222131 data-v-72c755c2><!--[--><li data-v-72c755c2><a class="VPSocialLink no-icon" href="https://github.com/Tencent/tmagic-editor" aria-label="github" target="_blank" rel="me noopener" data-v-72c755c2 data-v-121898e4><span class="vpi-simple-icons-github" data-v-121898e4 data-v-0ee3818a></span></a></li><!--]--></ul><!----><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="Menu" aria-expanded="false" data-v-5d7186a2 data-v-4d4764b1><span class="container" aria-hidden="true" data-v-4d4764b1><span class="top" data-v-4d4764b1></span><span class="middle" data-v-4d4764b1></span><span class="bottom" data-v-4d4764b1></span></span></button></div></div></div></div><div class="divider" data-v-5d7186a2><div class="divider-line" data-v-5d7186a2></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-440dbbdf data-v-9af4a020><div class="container" data-v-9af4a020><button type="button" class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-9af4a020><span class="vpi-align-left menu-icon" aria-hidden="true" data-v-9af4a020></span><span class="menu-text" data-v-9af4a020>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-allow-mismatch="style" data-v-9af4a020 data-v-67af6a22><button type="button" data-v-67af6a22>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-440dbbdf data-v-661d8e09><div class="curtain" data-v-661d8e09></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-661d8e09><span class="visually-hidden" id="sidebar-aria-label" data-v-661d8e09> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-e65c073a><section class="VPSidebarItem level-0 has-active" data-v-e65c073a data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h2 class="text" data-v-cab05059>编辑器</h2><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>Editor组件</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/props.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>props</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/slots.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>slots</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/events.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>events</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>editorService</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/editorServiceMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>方法</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/editorServiceEvents.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>事件</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>propsService</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/propsServiceMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>方法</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/propsServiceEvents.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>事件</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>historyService</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/historyServiceMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>方法</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/historyServiceEvents.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>事件</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><div class="VPSidebarItem level-1 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/eventsServiceMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>eventsService</p><!--]--></a><!----></div><!----></div><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>uiService</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/uiServiceMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>方法</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/uiServiceEvents.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>事件</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><div class="VPSidebarItem level-1 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/codeBlockServiceMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>codeBlockService</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/componentListServiceMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>componentListService</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/storageServiceMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>storageService</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link is-active has-active" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/editor/sdk.html" aria-current="page" data-v-cab05059><!--[--><p class="text" data-v-cab05059>DSL SDK(Node)</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section></div><div class="no-transition group" data-v-e65c073a><section class="VPSidebarItem level-0" data-v-e65c073a data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h2 class="text" data-v-cab05059>表单</h2><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>Form组件</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/form/form-props.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>props</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/form/form-methods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>methods</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/form/form-events.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>events</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>FormDialog组件</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/form/form-dialog-props.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>props</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/form/form-dialog-methods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>methods</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/form/form-dialog-events.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>events</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>工具函数</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/form/submit-form.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>submitForm</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><!--]--></li></ul></section></div><div class="no-transition group" data-v-e65c073a><section class="VPSidebarItem level-0" data-v-e65c073a data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h2 class="text" data-v-cab05059>表格</h2><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>Table组件</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/table/props.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>props</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/table/methods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>methods</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/table/events.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>events</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><!--]--></li></ul></section></div><div class="no-transition group" data-v-e65c073a><section class="VPSidebarItem level-0" data-v-e65c073a data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h2 class="text" data-v-cab05059>stage</h2><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><section class="VPSidebarItem level-1" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><h3 class="text" data-v-cab05059>StageCore</h3><!----></div><ul class="items" data-v-cab05059><li data-v-cab05059><!--[--><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/stage/coreMethods.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>方法</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-cab05059><div class="item" data-v-cab05059><div class="indicator" data-v-cab05059></div><a class="VPLink link link" href="/tmagic-editor/docs/api/stage/coreEvents.html" data-v-cab05059><!--[--><p class="text" data-v-cab05059>事件</p><!--]--></a><!----></div><!----></div><!--]--></li></ul></section><!--]--></li></ul></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-440dbbdf data-v-9677ef77><div class="VPDoc has-sidebar has-aside" data-v-9677ef77 data-v-5a9131ba><!--[--><!--]--><div class="container" data-v-5a9131ba><div class="aside" data-v-5a9131ba><div class="aside-curtain" data-v-5a9131ba></div><div class="aside-container" data-v-5a9131ba><div class="aside-content" data-v-5a9131ba><div class="VPDocAside" data-v-5a9131ba data-v-94896f55><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-94896f55 data-v-8d793e1b><div class="content" data-v-8d793e1b><div class="outline-marker" data-v-8d793e1b></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-8d793e1b>On this page</div><ul class="VPDocOutlineItem root" data-v-8d793e1b data-v-c684cb5d><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-94896f55></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-5a9131ba><div class="content-container" data-v-5a9131ba><!--[--><!--]--><main class="main" data-v-5a9131ba><div style="position:relative;" class="vp-doc _tmagic-editor_docs_api_editor_sdk" data-v-5a9131ba><div><h1 id="dsl-sdk-tmagic-editor-sdk" tabindex="-1">DSL SDK(<code>@tmagic/editor/sdk</code>) <a class="header-anchor" href="#dsl-sdk-tmagic-editor-sdk" aria-label="Permalink to “DSL SDK(@tmagic/editor/sdk)”">​</a></h1><p>不依赖 DOM / Vue 界面 / 画布的 DSL 操作 SDK,只负责对 DSL 做增删改查、历史撤销重做、依赖收集与合法性校验,可以直接在 Node 中运行(比如给 AI agent 调用的命令行工具使用)。</p><p>浏览器端的 <code>editorService</code>、<code>historyService</code> 等单例就是用同一个工厂创建的默认实例,因此 <code>import { editorService } from &#39;@tmagic/editor&#39;</code> 的用法不受影响。</p><div class="language-ts"><button title="Copy code" data-copied="Copied" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { createDslSdk } </span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@tmagic/editor/sdk&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span></code></pre></div><h2 id="快速开始" tabindex="-1">快速开始 <a class="header-anchor" href="#快速开始" aria-label="Permalink to “快速开始”">​</a></h2><div class="language-ts"><button title="Copy code" data-copied="Copied" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { createDslSdk } </span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@tmagic/editor/sdk&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> sdk</span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createDslSdk</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;"> // 初始 DSL,会被深拷贝,不会修改传入的对象</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> dsl: { type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;app&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;app_1&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, items: [{ type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;page&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;page_1&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;index&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, items: [] }] },</span></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;"> // 此前通过 sdk.serializeHistory() 导出的历史快照(可选)</span></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;"> // history,</span></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;"> // 组件列表:用来判断新增的组件类型是否合法</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> componentGroupList: [{ title: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;基础&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, items: [{ text: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;文本&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;text&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }] }],</span></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;"> // 组件属性表单配置,key 是组件 type,值是该组件的表单配置(FormConfig,即表单项数组):用来校验属性是否合法</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> propsConfigs: {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> text: [{ type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;text&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, name: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;text&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, text: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;文本&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, rules: [{ required: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, message: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;文本不能为空&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }] }],</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;"> // 组件被添加时的初始值,与 propsConfigs 的 key 一一对应</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> propsValues: { text: { text: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;文本&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> } },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.ready; </span><span style="--shiki-light:#62687b;--shiki-dark:#818e99;">// 登记表(含异步的属性配置)全部就绪</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;">// 没有选中节点时,默认添加到第一个页面;id 由 SDK 生成,后续操作使用返回值里的 id</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> node</span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.editor.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">add</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;text&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, text: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;hello&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.editor.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">update</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ id: node.id, text: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;world&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.editor.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">undo</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;">// 属性不合法时(strict 模式)会抛出 DslValidationError,且不会修改 DSL</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.editor.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">update</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ id: node.id, text: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }).</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">((</span><span style="--shiki-light:#c13617;--shiki-dark:#FFAB70;">e</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">=&gt;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(e.errors)); </span><span style="--shiki-light:#62687b;--shiki-dark:#818e99;">// [{ ..., message: &#39;文本 -&gt; 文本不能为空&#39; }]</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> newDsl</span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getDsl</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(); </span><span style="--shiki-light:#62687b;--shiki-dark:#818e99;">// 深拷贝,已包含依赖收集结果</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> newHistory</span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">serializeHistory</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(); </span><span style="--shiki-light:#62687b;--shiki-dark:#818e99;">// 可 JSON.stringify,下次作为 history 传回</span></span></code></pre></div><div class="tip custom-block"><p class="custom-block-title custom-block-title-default">TIP</p><p><code>propsConfigs</code> 的格式与 <a href="./props.html#propsconfigs">Editor 的 propsConfigs</a> 相同。实际项目中通常直接使用 runtime 构建出来的 <code>magicPresetConfigs</code> / <code>magicPresetValues</code>(参考<a href="./../../guide/#propsconfigs-propsvalues">快速开始</a>),在 Node 中加载构建产物后传入即可。</p></div><h2 id="无状态使用" tabindex="-1">无状态使用 <a class="header-anchor" href="#无状态使用" aria-label="Permalink to “无状态使用”">​</a></h2><p>每次调用传入「DSL + 历史快照」,操作完成后导出新的「DSL + 历史快照」:</p><div class="language-ts"><button title="Copy code" data-copied="Copied" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">const</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> sdk</span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> createDslSdk</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ dsl: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">readJson</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;dsl.json&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">), history: </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">readJson</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;history.json&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) });</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.editor.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">update</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ id: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;button_1&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, text: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;new&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">writeJson</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;dsl.json&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, sdk.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">getDsl</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">());</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">writeJson</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;history.json&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, sdk.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">serializeHistory</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">());</span></span></code></pre></div><div class="tip custom-block"><p class="custom-block-title custom-block-title-default">TIP</p><ul><li><code>serializeHistory()</code> 导出的快照可以直接 <code>JSON.stringify</code>;浏览器端 <code>historyService.serialize()</code> 默认保留 <code>Map</code>,适合写入 IndexedDB。</li><li>Node 下默认的 <code>parseDSL</code> 只解析 JSON,不会执行代码;如果历史里包含函数 / 正则,请自行传入 <code>parseDSL</code>。</li></ul></div><h2 id="createdslsdk-options" tabindex="-1">createDslSdk(options) <a class="header-anchor" href="#createdslsdk-options" aria-label="Permalink to “createDslSdk(options)”">​</a></h2><p>每次调用返回一组相互连线、互相独立的 service,多个实例互不影响。</p><h3 id="options" tabindex="-1">options <a class="header-anchor" href="#options" aria-label="Permalink to “options”">​</a></h3><table tabindex="0"><thead><tr><th>参数</th><th>说明</th><th>默认值</th></tr></thead><tbody><tr><td><code>dsl</code></td><td>初始 DSL</td><td>-</td></tr><tr><td><code>history</code></td><td>历史快照</td><td>-</td></tr><tr><td><code>validateMode</code></td><td>校验模式,见<a href="#校验">校验</a></td><td><code>&#39;strict&#39;</code></td></tr><tr><td><code>autoWiring</code></td><td>是否自动绑定依赖收集连线</td><td><code>true</code></td></tr><tr><td><code>reactivity</code></td><td>响应式实现:<code>reactive</code> / <code>shallowReactive</code> / <code>toRaw</code> / <code>nextTick</code>,默认使用 Vue 的实现,可覆盖</td><td>Vue</td></tr><tr><td><code>storage</code></td><td>存储适配器(<code>localStorage</code> 天然满足),用于复制粘贴、代码块草稿</td><td>内存实现 <code>MemoryStorage</code></td></tr><tr><td><code>parseDSL</code></td><td>把序列化字符串还原成值</td><td>只解析 JSON</td></tr><tr><td><code>historyPersistence</code></td><td>历史持久化适配器 <code>{ get, set }</code>(浏览器端对应 IndexedDB),不提供时 <code>saveToIndexedDB</code> / <code>restoreFromIndexedDB</code> 会 reject</td><td>-</td></tr><tr><td><code>collectWorker</code></td><td>依赖收集 worker 适配器,不提供则在主线程收集</td><td>-</td></tr><tr><td><code>copyText</code> / <code>notify</code></td><td>复制到剪贴板、提示信息,不提供则不做任何事</td><td>-</td></tr><tr><td><code>componentGroupList</code> / <code>propsConfigs</code> / <code>propsValues</code> / <code>eventMethodList</code> / <code>datasourceList</code> / <code>datasourceConfigs</code> / <code>datasourceValues</code> / <code>datasourceEventMethodList</code> / <code>disabledCodeBlock</code> / <code>disabledDataSource</code> / <code>disabledPageFragment</code> / <code>disabledMultiSelect</code> / <code>alwaysMultiSelect</code> / <code>canDropIn</code></td><td>登记表,与 <a href="./props.html">Editor props</a> 同名项一一对应</td><td>-</td></tr></tbody></table><h3 id="返回值" tabindex="-1">返回值 <a class="header-anchor" href="#返回值" aria-label="Permalink to “返回值”">​</a></h3><table tabindex="0"><thead><tr><th>属性</th><th>说明</th></tr></thead><tbody><tr><td><code>editor</code> / <code>history</code> / <code>props</code> / <code>dataSource</code> / <code>codeBlock</code> / <code>dep</code> / <code>storage</code> / <code>events</code> / <code>componentList</code></td><td>各 service 实例,方法与浏览器端同名 service 一致</td></tr><tr><td><code>validate</code></td><td>校验器,见<a href="#校验">校验</a></td></tr><tr><td><code>ctx</code></td><td>service 之间共享的上下文</td></tr><tr><td><code>ready</code></td><td>登记表全部就绪后 resolve</td></tr><tr><td><code>getDsl()</code></td><td>导出当前 DSL(深拷贝)</td></tr><tr><td><code>setDsl(dsl)</code></td><td>整体替换 DSL,会写入历史记录,返回的 Promise 在自动选中节点完成后 resolve</td></tr><tr><td><code>serializeHistory()</code></td><td>导出可 JSON 序列化的历史快照</td></tr><tr><td><code>bindWiring()</code></td><td>绑定依赖收集连线(<code>autoWiring: false</code> 时手动调用),返回解绑函数。绑定时如果 DSL 已经设置,会立即补做一次依赖收集</td></tr><tr><td><code>destroy()</code></td><td>销毁</td></tr></tbody></table><h2 id="校验" tabindex="-1">校验 <a class="header-anchor" href="#校验" aria-label="Permalink to “校验”">​</a></h2><p><code>validateMode</code> 决定修改 DSL 时如何处理不合法的内容:</p><ul><li><code>strict</code>:修改前校验,不通过抛出 <code>DslValidationError</code>(<code>errors</code> 里是全部问题),<strong>DSL 不会被修改</strong>,适合给 agent 调用,agent 可以根据 <code>errors</code> 修正后重试。Node 下默认。</li><li><code>record</code>:不抛错,把校验结果写进 <code>editor.state.invalidNodeIds</code>。</li><li><code>off</code>:不做额外校验。浏览器端默认实例使用这个模式(属性面板自己负责校验)。</li></ul><p>可以通过 <code>sdk.ctx.validateMode = &#39;off&#39;</code> 在运行时切换。</p><p>校验内容:</p><table tabindex="0"><thead><tr><th>类别</th><th>内容</th></tr></thead><tbody><tr><td>结构(<code>kind: &#39;structure&#39;</code>)</td><td>组件类型是否在组件列表中(<code>page</code> / <code>page-fragment</code> / <code>container</code> 内置合法,组件列表为空时不校验)、父节点是否是容器、<code>canDropIn</code>、是否禁用页面片、id 是否重复、不允许修改节点类型、数据源类型是否可用</td></tr><tr><td>属性(<code>kind: &#39;props&#39;</code>)</td><td>用 <code>@tmagic/form/headless</code> 的 <code>validateForm</code> 校验节点 / 数据源的属性表单配置,包含 <code>typeMatch</code></td></tr></tbody></table><div class="language-ts"><button title="Copy code" data-copied="Copied" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { DslValidationError } </span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &#39;@tmagic/editor/sdk&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">try</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.editor.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">add</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ type: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;unknown&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">catch</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (e) {</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> (e </span><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">instanceof</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> DslValidationError</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> console.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">log</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(e.errors); </span><span style="--shiki-light:#62687b;--shiki-dark:#818e99;">// [{ target, id, path, kind, message, suggestion }]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#62687b;--shiki-dark:#818e99;">// 主动校验</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.validate.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">node</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;text_1&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.validate.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">dataSource</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&#39;ds_1&#39;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">);</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;">await</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> sdk.validate.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">dsl</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">();</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title custom-block-title-default">WARNING</p><ul><li>数据源的 <code>add</code> / <code>update</code> 是同步方法,只做同步的结构校验(数据源类型是否可用);属性校验请用 <code>sdk.validate.dataSource(id)</code>。</li><li>SDK 内只注册了 <code>@tmagic/form/headless</code> 的内置字段,编辑器自定义字段(<code>data-source-select</code>、<code>code-select</code> 等)的 <code>typeMatch</code> 依赖编辑器的单例 service,不在 SDK 校验范围内;需要时可在浏览器环境下通过 <code>@tmagic/editor/headless</code> 的 <code>editorFields</code> 注册。</li></ul></div><h2 id="依赖收集" tabindex="-1">依赖收集 <a class="header-anchor" href="#依赖收集" aria-label="Permalink to “依赖收集”">​</a></h2><p><code>autoWiring</code> 为 <code>true</code> 时,节点、数据源、代码块发生变化会同步收集依赖,并把结果写回 DSL 的 <code>dataSourceDeps</code> / <code>dataSourceCondDeps</code> / <code>dataSourceMethodDeps</code>,所以操作返回时导出的 DSL 依赖信息已经是最新的。</p><p>不需要依赖收集(只做 DSL 增删改)时可以传 <code>autoWiring: false</code>,之后需要时再调用 <code>sdk.bindWiring()</code>;注意关闭期间不会同步数据源 / 代码块与依赖目标,也不会自动选中页面。</p><h2 id="插件" tabindex="-1">插件 <a class="header-anchor" href="#插件" aria-label="Permalink to “插件”">​</a></h2><p>所有 service 都支持 <code>usePlugin</code>,与浏览器端一致:</p><div class="language-ts"><button title="Copy code" data-copied="Copied" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark" style="--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e;" tabindex="0" dir="ltr"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">sdk.editor.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">usePlugin</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> beforeAdd</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#c13617;--shiki-dark:#FFAB70;">addNode</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#c13617;--shiki-dark:#FFAB70;">parent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
<span class="line"><span style="--shiki-light:#c62739;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [addNode, parent];</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div></div></div></main><footer class="VPDocFooter" data-v-5a9131ba data-v-0e42eeea><!--[--><!--]--><!----><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-0e42eeea><span class="visually-hidden" id="doc-footer-aria-label" data-v-0e42eeea>Pager</span><div class="pager" data-v-0e42eeea><a class="VPLink link pager-link prev" href="/tmagic-editor/docs/api/editor/storageServiceMethods.html" data-v-0e42eeea><!--[--><span class="desc" data-v-0e42eeea>Previous page</span><span class="title" data-v-0e42eeea>storageService</span><!--]--></a></div><div class="pager" data-v-0e42eeea><a class="VPLink link pager-link next" href="/tmagic-editor/docs/api/form/form-props.html" data-v-0e42eeea><!--[--><span class="desc" data-v-0e42eeea>Next page</span><span class="title" data-v-0e42eeea>props</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-440dbbdf data-v-2daa7712><div class="container" data-v-2daa7712><p class="message" data-v-2daa7712>Powered by 腾讯视频会员平台技术中心</p><p class="copyright" data-v-2daa7712>Copyright (C) 2025 Tencent.</p></div></footer><!--[--><!--]--></div></div>
</body>
</html>