designer-core
存放设计器的通用功能。
安装依赖
npm install designer-core
基于类的部件
WidgetDesignable
是 Widget 的 Mixin,将用户自定义部件扩展为可在设计器中使用的部件,即为部件添加以下交互功能:
- 测量聚焦部件的尺寸,以便为部件添加聚焦框;
- 测量光标指向部件的尺寸,以便为部件添加高亮框;
- 增加遮盖层,屏蔽部件默认的聚焦效果以及与设计器冲突的事件;
- 为空容器增加可视化效果等;
- 支持在部件中修改指定属性的值。
注意:WidgetDesignable
只适用于基于类的部件,不能与基于函数的部件一起使用。
通过以下方式实现:
- 根据部件内部的
key
定位到一个VNode
,然后在此VNode
上绑定默认的onMouseUp
事件; - ...
自定义部件
约定:
- 每个部件的根节点都需要设置
key
属性,将设置key
的代码提取到getRootKey(): string
方法中;
如何开发设计器版部件
设计器版部件是基于上面定义的自定义部件扩展的。
-
创建基于类的设计器部件;
-
导入
WidgetDesignableMixin
; -
设计器部件继承自混入了
WidgetDesignableMixin
的自定义部件// 因为要将设计器版部件也取名为 Page,所以将用户自定义部件重命名为 PageBase// 即约定加上 Base 后缀; -
为部件添加遮盖层。在设计器版部件中覆写
needOverlay
方法(默认返回false
),输入框之类的部件需要在设计器中屏蔽点击事件等。protected needOverlay: boolean -
支持在部件中直接编辑指定的属性,在此方法中指定可直接编辑的属性名。通常需要覆写 web 版部件,让其支持编辑功能。
protected getCanEditingPropertyName: string | undefined
示例
-
自定义部件
page/index.tsx
;;; -
设计器版部件
page/index.ts
;// 注意:WidgetDesignableMixin 一定要用大括号括住;
基于函数的部件
ide
中间件专用于为基于函数的部件添加在设计器中交互功能。在部件中添加 ide
中间件即可。
; ; ;
设计器插件
设计器插件是一种集成方式,用于将第三方的 Widget 或功能组件集成到页面设计器中。要在入口文件(通常是 main.ts
)的最后调用 blocklang.registerWidgets
函数来注册部件。设计器插件要发布为 Webpack Library,然后通过动态添加 script
节点来加载插件,当插件加载完成后,会执行 blocklang.registerWidgets
函数。
定义 TextInput
部件
text-input/index.ts
定义 TextInput
的属性面板
text-input/propertiesLayout.ts
;
在 main.ts
文件中调用 blocklang.registerWidgets()
函数注册 Widget
注意:在注册部件时,部件的 key 值必须与 API 仓库中定义的部件名相同,具体是指新建部件时指定的 name
属性,即 changelog 文件中 newWidget
操作中的 name
属性。因为在设计器中会根据这个 name
属性查找 IDE 版部件类。如以下代码中的 key 值为 TextInput
。
main.ts
;; // 通常位于非设计器版的仓库中,此处;;; ; ;; blocklang.registerWidgetsgitUrlSegment, widgets; // 注意,当前只支持基于类的部件// 当使用基于类的部件,需要调用此函数缓存第三方库中的 widgetInstanceMap 对象// 如果是标准库,则不需要填写这段代码,因为标准库是直接 import 的blocklang.cacheWidgetInstanceMapgitUrlSegment, widgetInstanceMap;
从注册的 Widget 列表中获取其中一个 Widget:
;; ; // 注意,widgetName 必须与注册部件时为部件指定的 key 值相同;// 根据仓库的地址信息获取; // 直接根据仓库的 url 获取;// 预览时使用; // 设计时使用;
在页面设计器中监听并同步第三方库中 widgetInstanceMap 的变化
; blocklang.watchingWidgetInstanceMapwidgetInstanceMap;
注册中间件
以下内容专用于基于函数的部件。
第三方组件库中直接引用 @dojo/framework
中的 node
和 dimensions
等中间件会无法获得 node 节点,因为第三方库中的 widget 都注册到 page-designer 项目中的 widgetMetaMap
对象中,而在第三方组件库中直接引用 @dojo/framework
中的 node
和 dimensions
等中间件时是从第三方库中的 widgetMetaMap
对象中查找部件,当然找不到了。所以此处需要将 page-designer 中的 dimensions
缓存到 global
对象中,然后在第三方库中使用此 dimensions
就可查找到部件。
在 page-designer 的顶层部件中调用 blocklang.registerDimensionsMiddleware(dimensions: any)
函数来注册 dimensions
:
;; blocklang.registerDimensionsMiddlewaredimensions;
在 designer-core 项目中的 ide
中间件中调用 blocklang.getDimensionsMiddleware()
函数来获取缓存的 dimensions
。