asai-vue-designer
v0.2.19
Published
asai for you
Readme
asai-vue-designer — HMI 可视化设计器
包信息
| 建议 npm 名 | 入口文件 | $fn / 注入键 | 类型 |
|------------|---------|-------------|------|
| @estun/asai-vue-designer | src/index.ts | AsaiVueDesigner → imComp + hooks | Feature |
概述
asai-vue-designer 为 AsaiWeb 低代码/HMI 场景提供所见即所得页面搭建:拖拽布局、属性面板、事件绑定、导入导出与多页面管理。
集成方式
// monorepo — 延迟:lib/featurePlugs.ts(非 App.vue 同步 import)
import AsaiVueDesigner from './plugs/asai-vue-designer/src/index';
// npm
// import AsaiVueDesigner from '@estun/asai-vue-designer';
const { ViewDesigner, useDesignerInit } = ujt.$fn.AsaiVueDesigner;独立性约束
- 禁止 cross-import 其它
plugs/*。 - 属性面板使用 Host 全局
AsaiForm(运行时);业务组件经opt.imComp/createComponentLoader注入。 buildCompMap定义于插件内components/_use/useCompLoader.ts(npm 包自包含)。
主要 API / 导出
| 导出 | 说明 |
|------|------|
| imComp.ViewDesigner | 画布主视图(async) |
| imComp.ViewDesignerIndex | 设计列表(async) |
| imComp.useDesignerInit | 初始化 $db.designerdata |
| imComp.useDesignerWc | 未保存/游戏得分 watch |
| imComp.AsStyle | 内联样式合成 |
designerdata.fn(useDesignerFn):readDesignData, saveDesignData, inDesigner, outDesigner 等。
性能说明
- 延迟加载(
featurePlugs);设计器 chunk 大,仅 cocontrol/HMI 路由需要。 useDesignerInit并行加载库 JSON + 列表;getComp缓存 async 组件解析。- glob 视图组件 async;
useDesignerWc使用flush: 'post'。 - 业务
imComp建议eager: false+cacheKey。
peerDependencies 建议
{
"peerDependencies": {
"vue": "^3.4.0",
"@estun/asai-vue-host": "^1.0.0",
"@estun/asai-vue-host-form": "^1.0.0",
"@estun/asai-vue-host-popbox": "^1.0.0"
}
}可视化页面设计器插件,为 AsaiWeb 低代码场景提供所见即所得的页面搭建能力:拖拽布局、样式编辑、事件绑定、导入导出与多页面管理。
快速接入
1. 注册插件
在宿主应用入口通过 $fn 访问(已由 featurePlugs 延迟挂载):
const { useDesignerInit, ViewDesigner } = $fn.AsaiVueDesigner;2. 顶层初始化(只需一次)
<script setup lang="ts">
const { useDesignerInit } = $fn.AsaiVueDesigner;
if (!$db.designerdata?.stat?.lib) {
useDesignerInit(props, {
dir: 'cocontrol/robotview/',
id: 'designer',
ty: 3,
fty: 'cocontrol',
devlevel: 1,
game: 0,
simple: 1,
url: { list: 'cocontrol/robotopt/config/designer/' },
path: { dbcfg: 'cocontrol/', db: './webdata/webdb/', dbtmp: './webdata/upload/' },
fns: funEvents,
});
}
</script>
<template>
<slot v-if="$db.designerdata?.stat?.lib" />
</template>3. 渲染设计器视图
列表页:
<ViewDesignerIndex :ujt="ujt" :designerdata="$db.designerdata" />画布页:
<script setup lang="ts">
const { ViewDesigner } = $fn.AsaiVueDesigner;
const { map: imComp, clear } = $fn.createComponentLoader({
files: import.meta.glob(['./_lib/!(_)*.vue']),
eager: false,
cache: true,
cacheKey: 'mydesigner_',
});
onUnmounted(() => clear());
</script>
<template>
<ViewDesigner :ujt="ujt" :designerdata="$db.designerdata" :opt="{ imComp }" />
</template>4. 挂载变更监听
const { useDesignerWc } = $fn.AsaiVueDesigner;
useDesignerWc(props);架构说明
宿主业务 (ViewArea / ViewShow)
useDesignerInit → $db.designerdata
useDesignerWc → 未保存 / 得分监听
↓
视图层 (_view/) — ViewDesignerIndex / ViewDesigner / 弹窗
↓
逻辑层 (_use/) — useDesignerFn / useFormAttr / asEvents
↓
表单 (_form/) + AsStyle + JSON 持久化数据流:
useDesignerInit并行加载组件库 + 设计列表- Hash 进入页面 →
readDesignData - 画布
<component :is>解析业务组件 - deep watch →
stat.datasaved = 0→ 保存 JSON
目录结构
asai-vue-designer/
├── src/index.ts
└── src/components/
├── ViewDesigner.vue / ViewDesignerIndex.vue
├── useDesignerInit.ts / useDesignerWc.ts
├── AsStyle.ts
├── _use/ # useDesignerFn, useFormAttr, useCompLoader …
├── _view/ # 工具栏、库、管理、属性
├── _form/ # 属性编辑表单组件
└── _css/核心数据模型
$db.designerdata 主要字段
| 字段 | 说明 |
|------|------|
| id / dir / ty | 实例 id、路由前缀、hash 段索引 |
| path | dbcfg / db / dbtmp |
| stat | lib/data 加载态,listsaved/datasaved |
| list | cfg + list |
| lib | type / comps / events / style / css |
| data | 当前页 cfg + data[] |
| ux | isedit / cur / ok / do |
| fn | useDesignerFn 方法集 |
设计项 data.data[i] 示例
{
"id": "ds-xxxx",
"label": "按钮-1234",
"comp": "MyButton",
"pos": { "x": 100, "y": 80, "w": 120, "h": 48 },
"events": ["fndownclick", { "typedrop": 0, "domev": [], "api": "" }],
"styles": { "styleok": "color:red;", "cssok": {} }
}API 参考
useDesignerInit(props, cfg?)
初始化 $db.designerdata 并并行加载库与列表。
useDesignerWc(props)
- 页面数据变更 →
stat.datasaved = 0 - 列表变更 →
stat.listsaved = 0 - 游戏得分达标 → 提示
useDesignerFn(designerdata.fn)
| 方法 | 说明 |
|------|------|
| initDesignLib | 加载 5 类库 JSON |
| readDesignList / saveDesignList | 列表 CRUD |
| readDesignData / saveDesignData | 当前页 CRUD |
| inDesigner / outDesigner | zip 导入导出 |
AsStyle
| 方法 | 说明 |
|------|------|
| renderStyle(props, type, itemdata) | 合成 style + css 内联 |
| getStyleByCss(cssdata) | 模板 → CSS 字符串 |
视图组件
| 组件 | 用途 |
|------|------|
| ViewDesignerIndex | 方案列表、maps、批量导入导出 |
| ViewDesigner | 画布主区域 |
| ViewDesignerItemArea / ViewDesignerItemOpt | 单项容器与操作条 |
| ViewDesignerBtns | 浮动工具栏 |
| ViewDesignerLibList / ViewDesignerManage / ViewDesignerAttr | 库、管理、属性弹窗 |
表单编辑组件(_form/)
| 组件 | 编辑内容 |
|------|----------|
| AsaiComp | 业务组件选择 |
| AsaiPos | x/y/w/h |
| AsaiStyle / AsaiStyles | 原子样式 |
| AsaiCss | CSS 模板参数 |
| AsaiEvent / AsaiDom | 事件与 DOM 目标 |
事件系统
解析优先级(asEvents.getfn):
designerdata.fns[name]— 业务自定义asEvents[name]— 内置
| 内置 | 行为 |
|------|------|
| fndownclick | 游戏模式标记完成 |
| fndownarrclick / fndragup | evAction 状态机 |
| fndownapi | WS API |
| fndownstyle | 追加内联样式 |
持久化路径
webdata/webdb/{id}/
├── designerlist.json
├── designer-{pageId}/design.json
└── lib/designertype.json …性能优化(已实现)
| 优化 | 效果 |
|------|------|
| 并行 init | 缩短首屏 |
| getComp 缓存 | 避免 v-for 重复 defineAsyncComponent |
| okSet O(1) | 游戏完成态 |
| useCompLoader | 插件内 glob → async 组件 |
扩展指南
新业务组件
_lib/MyWidget.vuecreateComponentLoader注册到opt.imCompdesignertype.json增加模板
自定义事件
useDesignerInit(props, {
fns: { myCustomEvent(props, ev, evd) { /* … */ } },
});仅预览
<ViewDesigner :opt="{ isview: 1, imComp }" … />典型集成参考
webclient/src/cocontrol/views/cocontrol/robotview/designer/_comps/ViewArea.vuewebclient/src/cocontrol/views/cocontrol/robotview/designer/_comps/ViewShow.vue
技术栈
Vue 3 + TS + Vite glob + SCSS + AsaiForm
