318 lines
14 KiB
HTML
318 lines
14 KiB
HTML
|
|
<!DOCTYPE html>
|
|||
|
|
<html lang="zh-CN">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
|
<title>步骤详解 - 创建 Helper 配置文件</title>
|
|||
|
|
<style>
|
|||
|
|
:root {
|
|||
|
|
--bg-primary: #0a0e1a;
|
|||
|
|
--bg-secondary: #111827;
|
|||
|
|
--bg-card: #1a2035;
|
|||
|
|
--bg-card-hover: #1f2a45;
|
|||
|
|
--border-color: #2d3a5c;
|
|||
|
|
--text-primary: #e2e8f0;
|
|||
|
|
--text-secondary: #94a3b8;
|
|||
|
|
--text-muted: #64748b;
|
|||
|
|
--accent-green: #10b981;
|
|||
|
|
--accent-green-light: #34d399;
|
|||
|
|
--accent-cyan: #06b6d4;
|
|||
|
|
--accent-purple: #8b5cf6;
|
|||
|
|
--accent-orange: #f59e0b;
|
|||
|
|
--shadow-lg: 0 10px 40px rgba(0, 0, 0, 0.4);
|
|||
|
|
}
|
|||
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|||
|
|
body {
|
|||
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|||
|
|
background: var(--bg-primary);
|
|||
|
|
color: var(--text-primary);
|
|||
|
|
line-height: 1.7;
|
|||
|
|
padding: 2rem;
|
|||
|
|
}
|
|||
|
|
.container { max-width: 1000px; margin: 0 auto; }
|
|||
|
|
.back-link {
|
|||
|
|
display: inline-flex; align-items: center; gap: 0.5rem;
|
|||
|
|
color: var(--accent-green-light); text-decoration: none;
|
|||
|
|
margin-bottom: 2rem; padding: 0.5rem 1rem;
|
|||
|
|
background: var(--bg-card); border-radius: 8px;
|
|||
|
|
border: 1px solid var(--border-color); transition: all 0.2s ease;
|
|||
|
|
}
|
|||
|
|
.back-link:hover { background: var(--bg-card-hover); transform: translateX(-4px); }
|
|||
|
|
.header {
|
|||
|
|
background: var(--bg-card); border-radius: 16px; padding: 2rem;
|
|||
|
|
margin-bottom: 2rem; border: 1px solid var(--border-color);
|
|||
|
|
box-shadow: var(--shadow-lg); border-left: 4px solid var(--accent-green);
|
|||
|
|
}
|
|||
|
|
.step-badge {
|
|||
|
|
display: inline-block; background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
|||
|
|
color: white; padding: 0.3rem 1rem; border-radius: 20px;
|
|||
|
|
font-size: 0.85rem; font-weight: 600; margin-bottom: 1rem;
|
|||
|
|
}
|
|||
|
|
.header h1 { font-size: 2rem; margin-bottom: 0.5rem; }
|
|||
|
|
.header .desc { color: var(--text-secondary); font-size: 1rem; }
|
|||
|
|
.section {
|
|||
|
|
background: var(--bg-card); border-radius: 12px; padding: 1.5rem;
|
|||
|
|
margin-bottom: 1.5rem; border: 1px solid var(--border-color);
|
|||
|
|
}
|
|||
|
|
.section h2 {
|
|||
|
|
font-size: 1.3rem; margin-bottom: 1rem; color: var(--accent-green-light);
|
|||
|
|
display: flex; align-items: center; gap: 0.5rem;
|
|||
|
|
}
|
|||
|
|
.section p { color: var(--text-secondary); margin-bottom: 1rem; }
|
|||
|
|
.code-block {
|
|||
|
|
background: var(--bg-secondary); padding: 1.25rem; border-radius: 8px;
|
|||
|
|
font-family: 'Fira Code', 'Cascadia Code', monospace; font-size: 0.85rem;
|
|||
|
|
color: var(--accent-cyan); overflow-x: auto; line-height: 1.6; margin-bottom: 1rem;
|
|||
|
|
}
|
|||
|
|
.code-block .comment { color: var(--text-muted); }
|
|||
|
|
.code-block .keyword { color: var(--accent-purple); }
|
|||
|
|
.code-block .string { color: var(--accent-green); }
|
|||
|
|
.method-table { width: 100%; border-collapse: separate; border-spacing: 0; margin-top: 1rem; }
|
|||
|
|
.method-table th {
|
|||
|
|
background: var(--bg-secondary); padding: 0.75rem 1rem; text-align: left;
|
|||
|
|
font-size: 0.85rem; color: var(--accent-orange); border-bottom: 1px solid var(--border-color);
|
|||
|
|
}
|
|||
|
|
.method-table td {
|
|||
|
|
padding: 0.75rem 1rem; border-bottom: 1px solid var(--border-color);
|
|||
|
|
font-size: 0.85rem; color: var(--text-secondary);
|
|||
|
|
}
|
|||
|
|
.method-table code {
|
|||
|
|
background: rgba(6, 182, 212, 0.1); color: var(--accent-cyan);
|
|||
|
|
padding: 0.15rem 0.4rem; border-radius: 4px; font-size: 0.8rem;
|
|||
|
|
}
|
|||
|
|
.info-grid {
|
|||
|
|
display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|||
|
|
gap: 1rem; margin-top: 1rem;
|
|||
|
|
}
|
|||
|
|
.info-card {
|
|||
|
|
background: var(--bg-secondary); padding: 1rem; border-radius: 8px;
|
|||
|
|
border: 1px solid var(--border-color);
|
|||
|
|
}
|
|||
|
|
.info-card h4 { font-size: 0.9rem; margin-bottom: 0.5rem; color: var(--accent-green-light); }
|
|||
|
|
.info-card p { font-size: 0.85rem; color: var(--text-secondary); margin: 0; }
|
|||
|
|
.file-path {
|
|||
|
|
font-family: 'Fira Code', monospace; font-size: 0.8rem;
|
|||
|
|
color: var(--accent-cyan); background: rgba(6, 182, 212, 0.1);
|
|||
|
|
padding: 0.25rem 0.5rem; border-radius: 4px;
|
|||
|
|
}
|
|||
|
|
ul { list-style: none; padding: 0; }
|
|||
|
|
ul li { padding: 0.4rem 0; color: var(--text-secondary); display: flex; align-items: flex-start; gap: 0.5rem; }
|
|||
|
|
ul li::before { content: "▸"; color: var(--accent-green); flex-shrink: 0; }
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="container">
|
|||
|
|
<a href="../../物料组件添加流程.html" class="back-link">← 返回主文档</a>
|
|||
|
|
|
|||
|
|
<div class="header">
|
|||
|
|
<div class="step-badge">步骤 3</div>
|
|||
|
|
<h1>创建 Helper 配置文件</h1>
|
|||
|
|
<p class="desc">定义物料组件的配置中心:物料面板、属性面板、拖拽行为等</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="section">
|
|||
|
|
<h2>📋 功能描述</h2>
|
|||
|
|
<p>Helper 是物料组件的<strong>配置中枢</strong>,定义了组件在物料面板的显示信息、右侧属性面板的表单 schema、拖入画布时的默认数据、拖拽行为规则等。它是连接设计器 UI 和组件实例的桥梁。</p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="section">
|
|||
|
|
<h2>🧩 模块描述</h2>
|
|||
|
|
<p>Helper 对象被 <code>RegisterWidgetHelper.ts</code> 导入并注册到系统,主要提供以下能力:</p>
|
|||
|
|
<ul>
|
|||
|
|
<li><strong>物料面板配置</strong> - 控制组件在左侧面板的图标、名称、分类</li>
|
|||
|
|
<li><strong>属性面板 Schema</strong> - 定义右侧属性面板的表单控件(输入框、选择器等)</li>
|
|||
|
|
<li><strong>默认 Widget 数据</strong> - 拖入画布时生成的初始 schema</li>
|
|||
|
|
<li><strong>拖拽行为</strong> - 控制组件拖入时的栅格占位</li>
|
|||
|
|
<li><strong>选择框配置</strong> - 控制组件是否可选中、复制、删除、隐藏</li>
|
|||
|
|
<li><strong>国际化路径</strong> - 指定需要国际化的属性路径</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="section">
|
|||
|
|
<h2>📁 文件信息</h2>
|
|||
|
|
<div class="info-grid">
|
|||
|
|
<div class="info-card">
|
|||
|
|
<h4>文件路径</h4>
|
|||
|
|
<p><span class="file-path">packages/form-designer/src/config/widget-helper/<组件名>Helper.ts</span></p>
|
|||
|
|
</div>
|
|||
|
|
<div class="info-card">
|
|||
|
|
<h4>操作类型</h4>
|
|||
|
|
<p><strong style="color: #34d399;">新建</strong> - 创建 Helper 配置对象</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="info-card">
|
|||
|
|
<h4>导出方式</h4>
|
|||
|
|
<p>默认导出 (export default) Helper 对象</p>
|
|||
|
|
</div>
|
|||
|
|
<div class="info-card">
|
|||
|
|
<h4>所属层级</h4>
|
|||
|
|
<p>页面设计器层 (packages/form-designer)</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="section">
|
|||
|
|
<h2>📊 Helper 接口方法</h2>
|
|||
|
|
<table class="method-table">
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>方法名</th>
|
|||
|
|
<th>返回值</th>
|
|||
|
|
<th>作用说明</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>type</code></td>
|
|||
|
|
<td>WidgetType</td>
|
|||
|
|
<td>组件唯一类型标识,与 WidgetType 枚举值对应</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>buildMaterialConfig()</code></td>
|
|||
|
|
<td>MaterialConfig</td>
|
|||
|
|
<td>物料面板显示配置:图标、名称、分类</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>buildSettings(params)</code></td>
|
|||
|
|
<td>WidgetSettingsConfig[]</td>
|
|||
|
|
<td>右侧属性面板的表单 schema(属性/样式/事件 tab)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>buildWidget(params)</code></td>
|
|||
|
|
<td>WidgetSchema</td>
|
|||
|
|
<td>拖入画布时生成的默认 schema(默认值、初始 props)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>dragInfo()</code></td>
|
|||
|
|
<td>{ col: number }</td>
|
|||
|
|
<td>拖拽时的栅格跨度(1-24)</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>hasSelectBox()</code></td>
|
|||
|
|
<td>SelectBoxConfig</td>
|
|||
|
|
<td>是否可选中、可否复制/删除/隐藏等</td>
|
|||
|
|
</tr>
|
|||
|
|
<tr>
|
|||
|
|
<td><code>collectLanguagePath()</code></td>
|
|||
|
|
<td>{ paths: string[][] }</td>
|
|||
|
|
<td>需要国际化的属性路径</td>
|
|||
|
|
</tr>
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="section">
|
|||
|
|
<h2>💻 完整代码示例</h2>
|
|||
|
|
<div class="code-block">
|
|||
|
|
<span class="comment">// packages/form-designer/src/config/widget-helper/MyNewComponentHelper.ts</span>
|
|||
|
|
|
|||
|
|
import { WidgetType } from '~@/types/WidgetType'
|
|||
|
|
|
|||
|
|
<span class="keyword">export default</span> {
|
|||
|
|
<span class="comment">// 1. 组件类型标识</span>
|
|||
|
|
type: WidgetType.MyNewComponent,
|
|||
|
|
|
|||
|
|
<span class="comment">// 2. 物料面板配置</span>
|
|||
|
|
buildMaterialConfig() {
|
|||
|
|
<span class="keyword">return</span> {
|
|||
|
|
icon: <span class="string">'icon-text'</span>, <span class="comment">// 图标类名</span>
|
|||
|
|
name: <span class="string">'MyNewComponent'</span>, <span class="comment">// 组件类型名</span>
|
|||
|
|
title: <span class="string">'新组件'</span>, <span class="comment">// 显示名称(在物料面板中显示)</span>
|
|||
|
|
category: <span class="string">'common'</span>, <span class="comment">// 分类:common/container/navigation 等</span>
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
<span class="comment">// 3. 右侧属性面板配置</span>
|
|||
|
|
buildSettings(params) {
|
|||
|
|
<span class="keyword">return</span> [
|
|||
|
|
{
|
|||
|
|
key: <span class="string">'property'</span>,
|
|||
|
|
label: <span class="string">'属性设置'</span>,
|
|||
|
|
type: <span class="string">'tab'</span>,
|
|||
|
|
children: [
|
|||
|
|
{
|
|||
|
|
key: <span class="string">'content'</span>,
|
|||
|
|
label: <span class="string">'文本内容'</span>,
|
|||
|
|
type: <span class="string">'input'</span>, <span class="comment">// form-create 内置控件类型</span>
|
|||
|
|
placeholder: <span class="string">'请输入内容'</span>,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
key: <span class="string">'fontSize'</span>,
|
|||
|
|
label: <span class="string">'字体大小'</span>,
|
|||
|
|
type: <span class="string">'inputNumber'</span>,
|
|||
|
|
min: 12,
|
|||
|
|
max: 72,
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
key: <span class="string">'color'</span>,
|
|||
|
|
label: <span class="string">'字体颜色'</span>,
|
|||
|
|
type: <span class="string">'colorPicker'</span>,
|
|||
|
|
},
|
|||
|
|
],
|
|||
|
|
},
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
<span class="comment">// 4. 拖入画布时生成的默认数据</span>
|
|||
|
|
buildWidget(params) {
|
|||
|
|
<span class="keyword">return</span> {
|
|||
|
|
type: <span class="keyword">this</span>.type,
|
|||
|
|
props: {
|
|||
|
|
content: <span class="string">'默认文本'</span>,
|
|||
|
|
fontSize: <span class="string">'14px'</span>,
|
|||
|
|
color: <span class="string">'#333333'</span>,
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
<span class="comment">// 5. 拖拽行为配置</span>
|
|||
|
|
dragInfo() {
|
|||
|
|
<span class="keyword">return</span> {
|
|||
|
|
col: 12, <span class="comment">// 占 12/24 栅格</span>
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
<span class="comment">// 6. 选择框配置</span>
|
|||
|
|
hasSelectBox() {
|
|||
|
|
<span class="keyword">return</span> {
|
|||
|
|
selectable: <span class="keyword">true</span>, <span class="comment">// 是否可选中</span>
|
|||
|
|
deletable: <span class="keyword">true</span>, <span class="comment">// 是否可删除</span>
|
|||
|
|
copyable: <span class="keyword">true</span>, <span class="comment">// 是否可复制</span>
|
|||
|
|
hideable: <span class="keyword">false</span>, <span class="comment">// 是否可隐藏</span>
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
<span class="comment">// 7. 国际化路径</span>
|
|||
|
|
collectLanguagePath() {
|
|||
|
|
<span class="keyword">return</span> {
|
|||
|
|
paths: [
|
|||
|
|
[<span class="string">'widget'</span>, <span class="string">'MyNewComponent'</span>, <span class="string">'content'</span>],
|
|||
|
|
],
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="section">
|
|||
|
|
<h2>⚠️ 注意事项</h2>
|
|||
|
|
<ul>
|
|||
|
|
<li><code>type</code> 必须与 WidgetType 枚举值完全一致</li>
|
|||
|
|
<li><code>buildSettings</code> 中的 type 使用 form-create 内置控件类型</li>
|
|||
|
|
<li><code>buildWidget</code> 返回的 props 结构需与 Vue 组件的 props 定义匹配</li>
|
|||
|
|
<li>复杂组件可实现 <code>transformSchemaProperties</code> 和 <code>buildSchemaController</code> 方法</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="section" style="border-left: 4px solid var(--accent-green);">
|
|||
|
|
<h2>➡️ 下一步</h2>
|
|||
|
|
<p>完成 Helper 配置后,继续执行:</p>
|
|||
|
|
<ul>
|
|||
|
|
<li><strong>步骤 4</strong>:在 RegisterWidget.ts 中注册组件实例</li>
|
|||
|
|
<li><strong>步骤 5</strong>:在 RegisterWidgetHelper.ts 中注册 Helper</li>
|
|||
|
|
<li><strong>步骤 6</strong>:在 Material.ts 中注册物料面板分组</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</body>
|
|||
|
|
</html>
|