外边暮雪 發表於 2025-12-9 10:45:00

【技术干货】如何在Vaadin应用程序中使用自定义Figma组件

<p><img src="https://image.evget.com/attachment/keditor/image/20251209/100106_6.png"></p>
<p><strong>Vaadin&nbsp;</strong>是一个面向企业级应用的现代 Web 开发框架,专注于&nbsp;<strong>Java 全栈开发、组件化 UI 构建</strong>,并提供丰富的开箱即用 Web Components。Vaadin 的优势包括:</p>
<ul>
<li>
<p><strong>Java 到前端的统一开发体验</strong></p>
</li>
<li>
<p><strong>企业级安全性与长生命周期支持</strong></p>
</li>
<li>
<p><strong>高质量 UI 组件库与设计系统</strong></p>
</li>
<li>
<p><strong>与 Figma 无缝衔接的 Copilot AI 辅助开发能力</strong></p>
</li>
</ul>
<p>在最新版本中,<strong>Vaadin Copilot</strong>&nbsp;新增了&nbsp;<strong>Figma Importer API</strong>,实现“从设计到代码”的自动化,让开发者可以直接将 Figma 组件复制并粘贴到 Vaadin 项目中,生成 Java 或 React 代码。</p>
<p>本文基于 Vaadin 官方示例并由慧都整理改写,帮助国内开发者快速上手。</p>
<p style="text-align: center"><span style="color: rgba(230, 126, 35, 1)"><strong>获取Vaadin产品试用&nbsp; 请联系慧都科技&gt;&gt;&gt;</strong></span></p>
<hr>
<h3><strong>1. 功能概览:从 Figma 复制、到 Vaadin 自动生成代码</strong></h3>
<p>通过<strong>&nbsp;Vaadin Copilot</strong>&nbsp;的&nbsp;<strong>Figma Importer API</strong>,你可以做到:</p>
<ul>
<li>
<p>从 Figma 复制组件或实例(如卡片、按钮)</p>
</li>
<li>
<p>在 Vaadin 项目中直接粘贴</p>
</li>
<li>
<p>自动生成对应的&nbsp;<strong>Java(Flow)</strong>&nbsp;或&nbsp;<strong>React(Hilla)</strong>&nbsp;组件代码</p>
</li>
</ul>
<p><img src="https://blog.vaadin.com/hs-fs/hubfs/undefined-Dec-01-2025-01-02-00-9097-PM.png?width=1600&amp;height=362&amp;name=undefined-Dec-01-2025-01-02-00-9097-PM.png"></p>
<p><em><span dir="auto">Figma Importer API 用于将 Simple Design System Card 映射到 Java SDSCard 组件。</span></em></p>
<p><span dir="auto">官方项目基于:</span></p>
<ul>
<li>
<p>Demo 项目</p>
</li>
<li>
<p>Figma 组件与实例示例</p>
</li>
</ul>
<hr>
<h3><strong>2. 使用前准备</strong></h3>
<h4><strong>启用 Vite 热重载(推荐)</strong></h4>
<p>在 Spring Bootapplication.properties中加入:</p>
<pre class="prettyprint highlighter-hljs"><code>vaadin.frontend.hotdeploy=true</code></pre>
<hr>
<h3><strong>3. Figma 组件体系与 Importer API 原理</strong></h3>
<p>许多公司(包括 Vaadin)都有自己的 Figma 设计系统,也可使用公开设计系统(如 Simple Design System)。<br><strong>Vaadin Copilot</strong>&nbsp;24.9 引入的&nbsp;<strong>Figma Importer API</strong>&nbsp;用于将这些组件映射为真实代码。</p>
<h4><strong>Figma → Vaadin 的映射关系:</strong></h4>
<ul>
<li>
<p>Figma 的&nbsp;<strong>Component</strong>&nbsp;≈ Java/TS 中的&nbsp;<strong>class</strong></p>
</li>
<li>
<p>Figma 的&nbsp;<strong>Instance</strong>&nbsp;≈ Java/TS 中的&nbsp;<strong>object</strong></p>
</li>
<li>
<p>属性可被实例覆盖</p>
</li>
<li>
<p>通过“标记属性(marker property)”来区分组件类型</p>
</li>
</ul>
<p>例如,Figma 中 Card 组件的属性:</p>
<pre class="prettyprint highlighter-hljs"><code>type = SDSCard</code></pre>
<p>Importer 仅匹配带有此属性的组件。</p>
<hr>
<h3><strong>4. 目标 Java / React 组件示例</strong></h3>
<p>以 SDSCard 与 SDSButton 为例:</p>
<h4><strong>若手动创建 Java 组件:</strong></h4>
<pre class="prettyprint lang-java highlighter-hljs"><code>var sdscard = new SDSCard();
sdscard.setTitle("Great news!");
sdscard.setBody(sayHello);

var sdsbutton = new SDSButton();
sdsbutton.setLabel("Sure!");
sdscard.add(sdsbutton);</code></pre>
<p>若使用 React:</p>
<pre class="prettyprint highlighter-hljs"><code>&lt;SDSCard title="Great news!"&gt;
   &lt;span slot="body"&gt;Did you know that Vaadin Copilot can import Figma components?&lt;/span&gt;
   &lt;SDSButton label="Sure!" /&gt;
&lt;/SDSCard&gt;</code></pre>
<p>示例工程已包含这些组件。</p>
<hr>
<h3><strong>5. 编写 Importer:从 Figma 转换为 Java/React</strong></h3>
<p>Importer 是一个&nbsp;<strong>TypeScript 函数</strong>:</p>
<ul>
<li>
<p>输入 FigmaNode</p>
</li>
<li>
<p>输出 ComponentDefinition</p>
</li>
<li>
<p>根据目标语言(Java 或 React)生成代码结构</p>
</li>
</ul>
<hr>
<h4><strong>5.1 SDSCard Java Importer 示例</strong></h4>
<p>文件:frontend/sdscard-java-importer.ts</p>
<pre class="prettyprint highlighter-hljs"><code>function sdsCardJavaImporter(node, metadata) {
if (node.properties.type === 'SDSCard' &amp;&amp; metadata.target === 'java') {
    return {
      tag: 'SDSCard',
      props: {
      title: node.properties.title,
      body: {
          tag: 'Span',
          props: { text: node.properties.body },
          javaClass: 'com.vaadin.flow.component.html.Span',
      },
      },
      children: createChildrenDefinitions(node, metadata, n =&gt; {
      return n.properties.type === 'SDSButton';
      }),
      javaClass: 'test.vaadin.copilot.flow.testviews.ui.customcomponents.components.SDSCard',
    };
}
}
registerImporter(sdsCardJavaImporter);</code></pre>
<h4><strong>核心点说明:</strong></h4>
<ul>
<li>
<p>匹配type: SDSCard</p>
</li>
<li>
<p>生成 Java 组件结构</p>
</li>
<li>
<p>子组件过滤以查找 Button</p>
</li>
</ul>
<hr>
<h4><strong>5.2 SDSButton Java Importer</strong></h4>
<p>文件:frontend/sdsbutton-java-importer.ts</p>
<pre class="prettyprint highlighter-hljs"><code>function sdsButtonJavaImporter(node, metadata) {
if (node.properties.type === 'SDSButton' &amp;&amp; metadata.target === 'java') {
    return {
      tag: 'SDSButton',
      props: { label: node.properties.label },
      children: [],
      javaClass: 'test.vaadin.copilot.flow.testviews.ui.customcomponents.components.SDSButton',
    };
}
}
registerImporter(sdsButtonJavaImporter);</code></pre>
<h4><strong>5.3 SDSCard React Importer</strong></h4>
<p>文件:frontend/sdscard-react-importer.ts</p>
<pre class="prettyprint highlighter-hljs"><code>function sdsCardReactImporter(node, metadata) {
if (node.properties.type === 'SDSCard' &amp;&amp; metadata.target === 'react') {
    return {
      tag: 'SDSCard',
      props: { title: node.properties.title },
      children: [
      {
          tag: 'span',
          props: { slot: 'body' },
          children: ,
      },
      ...createChildrenDefinitions(node, metadata, n =&gt; n.properties.type === 'SDSButton'),
      ],
      reactImports: { SDSCard: 'Frontend/components/SDSCard' },
    };
}
}
registerImporter(sdsCardReactImporter);</code></pre>
<h4><strong>5.4 SDSButton React Importer</strong></h4>
<p>文件:frontend/sdsbutton-react-importer.ts</p>
<pre class="prettyprint highlighter-hljs"><code>function sdsButtonReactImporter(node, metadata) {
if (node.properties.type === 'SDSButton' &amp;&amp; metadata.target === 'react') {
    return {
      tag: 'SDSButton',
      props: { label: node.properties.label },
      children: [],
      reactImports: { SDSButton: 'Frontend/components/SDSButton' },
    };
}
}
registerImporter(sdsButtonReactImporter);</code></pre>
<h3><strong>6. 在项目中启用 Importer</strong></h3>
<h4><strong>Flow(Java)项目中:</strong></h4>
<pre class="prettyprint lang-java highlighter-hljs"><code>@SpringBootApplication
@JsModule(value = "./sdscard-java-importer.ts", developmentOnly = true)
@JsModule(value = "./sdsbutton-java-importer.ts", developmentOnly = true)
@JsModule(value = "./sdscard-react-importer.ts", developmentOnly = true)
@JsModule(value = "./sdsbutton-react-importer.ts", developmentOnly = true)
public class Application implements AppShellConfigurator {}</code></pre>
<p>React 项目:index.tsx</p>
<pre class="prettyprint lang-java highlighter-hljs"><code>if (import.meta.env.DEV) {
import('./sdscard-java-importer');
import('./sdsbutton-java-importer');
import('./sdscard-react-importer');
import('./sdsbutton-react-importer');
}</code></pre>
<h3><strong>7. 自动生成的代码示例</strong></h3>
<h4><strong>Java 生成代码:</strong></h4>
<pre class="prettyprint lang-java highlighter-hljs"><code>SDSCard sdscard = new SDSCard();
sdscard.setTitle("Great news!");
Span didYouKnowThatVaadin = new Span("Did you know that Vaadin Copilot can import Figma components?");
sdscard.setBody(didYouKnowThatVaadin);

SDSButton sure = new SDSButton();
sure.setLabel("Sure!");
sdscard.add(sure);

add(sdscard);</code></pre>
<p>React 生成代码:</p>
<pre class="prettyprint highlighter-hljs"><code>&lt;SDSCard title="Great news!"&gt;
   &lt;span slot="body"&gt;
      Did you know that Vaadin Copilot can import Figma components?
   &lt;/span&gt;
   &lt;SDSButton label="Sure!" /&gt;
&lt;/SDSCard&gt;</code></pre>
<h3><strong>Vaadin 25 版本更新提醒</strong></h3>
<p>在 Vaadin 25 中:</p>
<ul>
<li>
<p>_registerImporter→registerImporter</p>
</li>
<li>
<p>_createChildrenDefinitions→createChildrenDefinitions</p>
</li>
</ul>
<p>请注意 API 名称变更。</p>
<p>&nbsp;</p>
<p style="text-align: center"><span style="color: rgba(230, 126, 35, 1)"><strong>获取Vaadin产品试用&nbsp; 请联系慧都科技&gt;&gt;&gt;</strong></span></p><br><br>
来源:https://www.cnblogs.com/software-Development/p/19325312
頁: [1]
查看完整版本: 【技术干货】如何在Vaadin应用程序中使用自定义Figma组件