diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ec9f88..1086576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.15.1 + +新增useRegistFunc用于注册函数。 + +更新部分文档。 + ## 0.15.0 废弃storechanger与iframe容器。 diff --git a/packages/dooringx-dumi-doc/docs/ChangeLog/index.en.md b/packages/dooringx-dumi-doc/docs/ChangeLog/index.en.md index afbf5e9..1efba1c 100644 --- a/packages/dooringx-dumi-doc/docs/ChangeLog/index.en.md +++ b/packages/dooringx-dumi-doc/docs/ChangeLog/index.en.md @@ -5,6 +5,9 @@ nav: title: Change log order: 6 --- +## 0.15.1 +Useregistfunc is added to register functions. +Update some documents. ## 0.15.0 Discard storechanger and iframe containers. Add function configuration to unload correctly. @@ -107,7 +110,7 @@ Add animation component timeline. You can preview all animations better. The animation part is reconstructed, which can support the simultaneous configuration of multiple animations. The minimum value of canvas drag is changed to 0. ## 0.7.7 -Drag and drop to make the canvas smoother and move logically. +Optimize the drag logic of the canvas to move more smoothly. ## 0.7.6 The custom rightglobalcustom type on the right is changed to the function passed in config ## 0.7.5 diff --git a/packages/dooringx-dumi-doc/docs/ChangeLog/index.md b/packages/dooringx-dumi-doc/docs/ChangeLog/index.md index 8a0b1c7..aa89620 100644 --- a/packages/dooringx-dumi-doc/docs/ChangeLog/index.md +++ b/packages/dooringx-dumi-doc/docs/ChangeLog/index.md @@ -5,6 +5,12 @@ nav: title: 变更日志 order: 6 --- +## 0.15.1 + +新增useRegistFunc用于注册函数。 + +更新部分文档。 + ## 0.15.0 废弃storechanger与iframe容器。 diff --git a/packages/dooringx-dumi-doc/docs/Guide/index.en.md b/packages/dooringx-dumi-doc/docs/Guide/index.en.md index c0e5b5d..1f487a1 100644 --- a/packages/dooringx-dumi-doc/docs/Guide/index.en.md +++ b/packages/dooringx-dumi-doc/docs/Guide/index.en.md @@ -1,134 +1,269 @@ --- -title: Introduction +title: 介绍 toc: menu order: 1 nav: - title: Guide + title: 指南 order: 1 --- -### What is dooringx lib? -Dooringx lib is the base of dooringx and a visual drag and drop framework with dooringx plug-ins removed. + + + +### What is dooringx lib? + +Dooringx lib is the base of dooringx and a visual drag and drop framework with dooringx plug-ins removed。 + Dooringx lib provides its own set of data flow event mechanism, pop-up window and other solutions, which allows you to customize and develop your own visual drag and drop platform faster. -### How does dooringx lib work? -Dooringx lib maintains a set of data flow at runtime, which is mainly divided into JSON data part, left component part, right configuration item part, shortcut key part, pop-up window part, event and function part and data source part. + +### dooringx-lib 如何工作? + + Dooringx lib maintains a set of data flow at runtime, which is mainly divided into JSON data part, left component part, right configuration item part, shortcut key part, pop-up window part, event and function part and data source part. + In addition to providing basic drag, move, zoom, select all, rotate and other functions, it can also use exposed components. If you feel that the components are not customized enough, you can adjust the style or rewrite it yourself. -### Get started quickly -#### Installation -Install using NPM or yarn -```bash -npm i dooringx-lib + +### 快速上手 + +First create a folder, such as dooringx example. + +We recommend using UMI scaffold to quickly build our project. + +Use commands within folders`yarn create @umijs/umi-app `或` npx @umijs/create-umi-app` + +install dooringx-lib: + ``` -Reference Demo: +yarn add dooringx-lib +``` +Some components in lib come from antd and its icon. Antd and icon need to be installed. The animation part mainly uses animate CSS also needs to be installed. + +``` +yarn add antd @ant-design/icons animate.css +``` + +First, add a new route for preview display. Edit the in the root directory umirc. ts: + +```js + routes: [ + { + exact: false, + path: '/', + component: '@/layouts/index', + routes: [ + { path: '/', component: '@/pages/index' }, + { path: '/preview', component: '@/pages/preview' }, + { path: '/iframe', component: '@/pages/iframe' }, + ], + }, + ], +``` +New layouts are added under SRC to embed sub pages +```js +import { UserConfig } from 'dooringx-lib'; +import 'dooringx-lib/dist/dooringx-lib.esm.css'; +import { createContext, useState } from 'react'; +import { IRouteComponentProps } from 'umi'; +import plugin from '../plugin'; +import 'antd/dist/antd.css'; +import 'animate.css'; + +export const config = new UserConfig(plugin); +export const configContext = createContext(config); +config.i18n = false; +export default function Layout({ children }: IRouteComponentProps) { + return ( + {children} + ); +} +``` +Layout depends on a customized plugin. Let's simply make a test component. + +Add a plugin folder under SRC, index tsx: +```js +import { InitConfig } from 'dooringx-lib'; +import { LeftRegistComponentMapItem } from 'dooringx-lib/dist/core/crossDrag'; +import { PlayCircleOutlined } from '@ant-design/icons'; + +const LeftRegistMap: LeftRegistComponentMapItem[] = [ + { + type: 'basic', + component: 'button', + img: 'icon-anniu', + imgCustom: , + displayName: '按钮', + urlFn: () => import('./button'), + }, +]; + +export const defaultConfig: Partial = { + leftAllRegistMap: LeftRegistMap, + leftRenderListCategory: [ + { + type: 'basic', + icon: , + displayName: '基础', + }, + ], + initComponentCache: {}, + rightRenderListCategory: [], + initFunctionMap: {}, + initCommandModule: [], + initFormComponents: {}, +}; + +export default defaultConfig; +``` +src/plugin/button/index.tsx +```js +import { ComponentItemFactory } from 'dooringx-lib'; +import { Button } from 'antd'; + +const Dbutton = new ComponentItemFactory( + 'button', + '按钮', + {}, + { + width: 200, + height: 55, + }, + () => { + return ; + }, + true, +); +export default Dbutton; + + +``` +In Src / pages / index New editor code at TSX: + ```js import { -RightConfig, -Container, -useStoreState, -innerContainerDragUp, -LeftConfig, -ContainerWrapper, -Control, + RightConfig, + Container, + useStoreState, + innerContainerDragUp, + LeftConfig, + ContainerWrapper, + Control, } from 'dooringx-lib'; import { useContext } from 'react'; import { configContext } from '@/layouts'; import { useCallback } from 'react'; -import { PREVIEWSTATE } from '@/constant'; export const HeaderHeight = '40px'; export default function IndexPage() { -const config = useContext(configContext); -const everyFn = () => {}; -const subscribeFn = useCallback(() => { -localStorage.setItem(PREVIEWSTATE, JSON.stringify(config.getStore().getData())); -}, [config]); -const [state] = useStoreState(config, subscribeFn, everyFn); -return ( -
-
-head - - -
-
-
- -
- -<> - - - - -
- -
-
-
-); + const config = useContext(configContext); + const subscribeFn = useCallback(() => { + localStorage.setItem( + 'PREVIEWSTATE', + JSON.stringify(config.getStore().getData()), + ); + }, [config]); + const [state] = useStoreState(config, subscribeFn) + return ( +
+
+ head + +
+
+
+ +
+ + + <> + + + + +
+ +
+
+
+ ); } ``` -Preview iframe: -```html -
- -
-``` -Preview route: +At this point, start the project and you can see that the editor has been displayed. The canvas can also be placed correctly when dragging components. + +Add a corresponding page under pages of SRC: + +src/pages/preview/index.tsx ```js -import { PREVIEWSTATE } from '@/constant'; -import { Preview, UserConfig } from 'dooringx-lib'; -import plugin from '../../plugin'; -const config = new UserConfig(plugin); +import { configContext } from '@/layouts'; +import { Preview } from 'dooringx-lib'; +import { useContext } from 'react'; + function PreviewPage() { -const data = localStorage.getItem(PREVIEWSTATE); -if (data) { -try { -const json = JSON.parse(data); -config.resetData([json]); -} catch { -console.log('err'); -} -} -return ( -
- -
-); + const data = localStorage.getItem('PREVIEWSTATE'); + const config = useContext(configContext); + if (data) { + try { + const json = JSON.parse(data); + config.resetData([json]); + } catch { + console.log('err'); + } + } + return ( +
+ +
+ ); } + export default PreviewPage; ``` -For the API section, refer to API \ No newline at end of file + + +src/pages/iframe/index.tsx +```js +function IframePage() { + return ( +
+ +
+ ); +} +export default IframePage; + +``` + +At this time, after dragging the component into the canvas, click the button to enter the preview, and you can see that the preview state is also rendered. diff --git a/packages/dooringx-dumi-doc/docs/Guide/index.md b/packages/dooringx-dumi-doc/docs/Guide/index.md index a14debb..175d688 100644 --- a/packages/dooringx-dumi-doc/docs/Guide/index.md +++ b/packages/dooringx-dumi-doc/docs/Guide/index.md @@ -25,144 +25,247 @@ dooringx-lib 在运行时维护一套数据流,主要分为json数据部分, ### 快速上手 +首先创建个文件夹,例如dooringx-example。 -#### 安装 +我们推荐使用Umi脚手架快速搭建我们的项目。 -使用 npm 或者 yarn 安装 +在文件夹内使用命令`yarn create @umijs/umi-app `或` npx @umijs/create-umi-app` + +安装dooringx-lib: -```bash -npm i dooringx-lib ``` -参考demo: +yarn add dooringx-lib +``` +lib中部分组件来源于antd和其icon。需要安装antd和icon。动画部分主要使用了animate.css,也需要安装下。 + +``` +yarn add antd @ant-design/icons animate.css +``` + +首先新增路由,用于预览显示。编辑根目录下的.umirc.ts: + +```js + routes: [ + { + exact: false, + path: '/', + component: '@/layouts/index', + routes: [ + { path: '/', component: '@/pages/index' }, + { path: '/preview', component: '@/pages/preview' }, + { path: '/iframe', component: '@/pages/iframe' }, + ], + }, + ], +``` +src下新增layouts用于嵌套子页面 +```js +import { UserConfig } from 'dooringx-lib'; +import 'dooringx-lib/dist/dooringx-lib.esm.css'; +import { createContext, useState } from 'react'; +import { IRouteComponentProps } from 'umi'; +import plugin from '../plugin'; +import 'antd/dist/antd.css'; +import 'animate.css'; + +export const config = new UserConfig(plugin); +export const configContext = createContext(config); +config.i18n = false; +export default function Layout({ children }: IRouteComponentProps) { + return ( + {children} + ); +} +``` +layout依赖个人定制的plugin,我们简单做个测试组件。 + +src下新增plugin文件夹,index.tsx: +```js +import { InitConfig } from 'dooringx-lib'; +import { LeftRegistComponentMapItem } from 'dooringx-lib/dist/core/crossDrag'; +import { PlayCircleOutlined } from '@ant-design/icons'; + +const LeftRegistMap: LeftRegistComponentMapItem[] = [ + { + type: 'basic', + component: 'button', + img: 'icon-anniu', + imgCustom: , + displayName: '按钮', + urlFn: () => import('./button'), + }, +]; + +export const defaultConfig: Partial = { + leftAllRegistMap: LeftRegistMap, + leftRenderListCategory: [ + { + type: 'basic', + icon: , + displayName: '基础', + }, + ], + initComponentCache: {}, + rightRenderListCategory: [], + initFunctionMap: {}, + initCommandModule: [], + initFormComponents: {}, +}; + +export default defaultConfig; +``` +src/plugin/button/index.tsx +```js +import { ComponentItemFactory } from 'dooringx-lib'; +import { Button } from 'antd'; + +const Dbutton = new ComponentItemFactory( + 'button', + '按钮', + {}, + { + width: 200, + height: 55, + }, + () => { + return ; + }, + true, +); +export default Dbutton; + + +``` +在src/pages/index.tsx处新增编辑器代码: ```js import { - RightConfig, - Container, - useStoreState, - innerContainerDragUp, - LeftConfig, - ContainerWrapper, - Control, + RightConfig, + Container, + useStoreState, + innerContainerDragUp, + LeftConfig, + ContainerWrapper, + Control, } from 'dooringx-lib'; import { useContext } from 'react'; import { configContext } from '@/layouts'; import { useCallback } from 'react'; -import { PREVIEWSTATE } from '@/constant'; - export const HeaderHeight = '40px'; - export default function IndexPage() { - const config = useContext(configContext); + const config = useContext(configContext); + const subscribeFn = useCallback(() => { + localStorage.setItem( + 'PREVIEWSTATE', + JSON.stringify(config.getStore().getData()), + ); + }, [config]); + const [state] = useStoreState(config, subscribeFn) + return ( +
+
+ head + +
+
+
+ +
- const everyFn = () => {}; - - const subscribeFn = useCallback(() => { - localStorage.setItem(PREVIEWSTATE, JSON.stringify(config.getStore().getData())); - }, [config]); - - const [state] = useStoreState(config, subscribeFn, everyFn); - - return ( -
-
- head - - -
-
-
- -
- - - <> - - - - -
- -
-
-
- ); + + <> + + + + +
+ +
+
+
+ ); } ``` +此时启动项目,可以看见编辑器已经显示出来了。拖动组件时,也能正确置入画布。 +src的pages下新增对应的页面: - - -预览时preview套iframe: - -```html -
- -
-``` -preview路由: - +src/pages/preview/index.tsx ```js -import { PREVIEWSTATE } from '@/constant'; -import { Preview, UserConfig } from 'dooringx-lib'; -import plugin from '../../plugin'; - -const config = new UserConfig(plugin); +import { configContext } from '@/layouts'; +import { Preview } from 'dooringx-lib'; +import { useContext } from 'react'; function PreviewPage() { - const data = localStorage.getItem(PREVIEWSTATE); - if (data) { - try { - const json = JSON.parse(data); - config.resetData([json]); - } catch { - console.log('err'); - } - } - return ( -
- -
- ); + const data = localStorage.getItem('PREVIEWSTATE'); + const config = useContext(configContext); + if (data) { + try { + const json = JSON.parse(data); + config.resetData([json]); + } catch { + console.log('err'); + } + } + return ( +
+ +
+ ); } export default PreviewPage; ``` -有关 api 部分请参考 api +src/pages/iframe/index.tsx +```js +function IframePage() { + return ( +
+ +
+ ); +} +export default IframePage; + +``` + +此时拖拽组件进入画布后,点击按钮进入预览则可看见预览状态也被渲染出来了。 diff --git a/packages/dooringx-example/src/pages/document.ejs b/packages/dooringx-example/src/pages/document.ejs index 42a5303..044f74d 100644 --- a/packages/dooringx-example/src/pages/document.ejs +++ b/packages/dooringx-example/src/pages/document.ejs @@ -2,7 +2,7 @@ * @Author: yehuozhili * @Date: 2021-09-28 21:10:15 * @LastEditors: yehuozhili - * @LastEditTime: 2022-01-13 15:42:56 + * @LastEditTime: 2022-04-27 22:36:07 * @FilePath: \dooringx\packages\dooringx-example\src\pages\document.ejs --> @@ -10,7 +10,7 @@ - + Dooringx-example diff --git a/packages/dooringx-example/src/plugin/formComponents/input.tsx b/packages/dooringx-example/src/plugin/formComponents/input.tsx index cb86516..ff1a326 100644 --- a/packages/dooringx-example/src/plugin/formComponents/input.tsx +++ b/packages/dooringx-example/src/plugin/formComponents/input.tsx @@ -2,7 +2,7 @@ * @Author: yehuozhili * @Date: 2021-07-07 14:32:55 * @LastEditors: yehuozhili - * @LastEditTime: 2021-08-05 15:27:21 + * @LastEditTime: 2022-04-25 00:32:32 * @FilePath: \dooringx\packages\dooringx-example\src\plugin\formComponents\input.tsx */ import { deepCopy, UserConfig } from 'dooringx-lib'; diff --git a/packages/dooringx-example/src/plugin/registComponents/button.tsx b/packages/dooringx-example/src/plugin/registComponents/button.tsx index f2e2aa9..56edb91 100644 --- a/packages/dooringx-example/src/plugin/registComponents/button.tsx +++ b/packages/dooringx-example/src/plugin/registComponents/button.tsx @@ -2,7 +2,7 @@ * @Author: yehuozhili * @Date: 2021-07-07 14:35:38 * @LastEditors: yehuozhili - * @LastEditTime: 2022-04-24 20:42:01 + * @LastEditTime: 2022-04-27 22:24:23 * @FilePath: \dooringx\packages\dooringx-example\src\plugin\registComponents\button.tsx */ @@ -13,6 +13,7 @@ import { ComponentItemFactory, createPannelOptions, useDynamicAddEventCenter, + useRegistFunc, } from 'dooringx-lib'; import { FormMap } from '../formTypes'; import { ComponentRenderConfigProps } from 'dooringx-lib/dist/core/components/componentItem'; @@ -33,45 +34,41 @@ function ButtonTemp(pr: ComponentRenderConfigProps) { const [text, setText] = useState(''); const op1 = props.op1; - useEffect(() => { - let unRegist = () => {}; - if (op1) { - const functionCenter = eventCenter.getFunctionCenter(); - unRegist = functionCenter.register({ - id: `${pr.data.id}+changeText`, - fn: async (ctx, next, config, args: any, _eventList, iname) => { - const userSelect = iname.data; - const ctxVal = changeUserValue( - userSelect['改变文本数据源'], - args, - '_changeval', - config, - ctx - ); - const text = ctxVal[0]; - setText(text); - next(); - }, - config: [ - { - name: '改变文本数据源', - data: ['ctx', 'input', 'dataSource'], - options: { - receive: '_changeval', - multi: false, - }, + + const fn = useMemo(() => { + const functionCenter = eventCenter.getFunctionCenter(); + return functionCenter.register({ + id: `${pr.data.id}+changeText`, + fn: async (ctx, next, config, args: any, _eventList, iname) => { + const userSelect = iname.data; + const ctxVal = changeUserValue( + userSelect['改变文本数据源'], + args, + '_changeval', + config, + ctx + ); + const text = ctxVal[0]; + setText(text); + next(); + }, + config: [ + { + name: '改变文本数据源', + data: ['ctx', 'input', 'dataSource'], + options: { + receive: '_changeval', + multi: false, }, - ], - name: `${pr.data.id}+改变文本函数`, - componentId: pr.data.id, - }); - } - return () => { - if (pr.context === 'preview') { - unRegist(); // 必须在预览时注销,否则影响二次点击效果,不在预览注销影响编辑时跨弹窗 - } - }; - }, [op1]); + }, + ], + name: `${pr.data.id}+改变文本函数`, + componentId: pr.data.id, + }); + }, []); + + useRegistFunc(op1, pr.context, fn); + return (