update 0.15.1

This commit is contained in:
yehuozhili
2022-04-28 00:33:36 +08:00
parent 1a77517d74
commit 7ae87f157e
13 changed files with 554 additions and 271 deletions

View File

@@ -1,3 +1,9 @@
## 0.15.1
新增useRegistFunc用于注册函数。
更新部分文档。
## 0.15.0
废弃storechanger与iframe容器。

View File

@@ -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

View File

@@ -5,6 +5,12 @@ nav:
title: 变更日志
order: 6
---
## 0.15.1
新增useRegistFunc用于注册函数。
更新部分文档。
## 0.15.0
废弃storechanger与iframe容器。

View File

@@ -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<UserConfig>(config);
config.i18n = false;
export default function Layout({ children }: IRouteComponentProps) {
return (
<configContext.Provider value={config}>{children}</configContext.Provider>
);
}
```
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: <PlayCircleOutlined />,
displayName: '按钮',
urlFn: () => import('./button'),
},
];
export const defaultConfig: Partial<InitConfig> = {
leftAllRegistMap: LeftRegistMap,
leftRenderListCategory: [
{
type: 'basic',
icon: <HighlightOutlined />,
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 <Button>测试</Button>;
},
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 (
<div {...innerContainerDragUp(config)}>
<div style={{ height: HeaderHeight }}>
head
<button
onClick={() => {
window.open('/iframe');
}}
>
go preview
</button>
<button
onClick={() => {
window.open('/preview');
}}
>
go preview
</button>
</div>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: `calc(100vh - ${HeaderHeight})`,
width: '100vw',
}}
>
<div style={{ height: '100%' }}>
<LeftConfig config={config}></LeftConfig>
</div>
<ContainerWrapper config={config}>
<>
<Control
config={config}
style={{ position: 'fixed', bottom: '60px', right: '450px', zIndex: 100 }}
></Control>
<Container state={state} config={config} context="edit"></Container>
</>
</ContainerWrapper>
<div className="rightrender" style={{ height: '100%' }}>
<RightConfig state={state} config={config}></RightConfig>
</div>
</div>
</div>
);
const config = useContext(configContext);
const subscribeFn = useCallback(() => {
localStorage.setItem(
'PREVIEWSTATE',
JSON.stringify(config.getStore().getData()),
);
}, [config]);
const [state] = useStoreState(config, subscribeFn)
return (
<div {...innerContainerDragUp(config)}>
<div style={{ height: HeaderHeight }}>
head
<button
onClick={() => {
window.open('/iframe');
}}
>
go preview
</button>
</div>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: `calc(100vh - ${HeaderHeight})`,
width: '100vw',
}}
>
<div style={{ height: '100%' }}>
<LeftConfig config={config}></LeftConfig>
</div>
<ContainerWrapper config={config}>
<>
<Control
config={config}
style={{
position: 'fixed',
bottom: '60px',
right: '450px',
zIndex: 100,
}}
></Control>
<Container state={state} config={config} context="edit"></Container>
</>
</ContainerWrapper>
<div className="rightrender" style={{ height: '100%' }}>
<RightConfig state={state} config={config}></RightConfig>
</div>
</div>
</div>
);
}
```
Preview iframe:
```html
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<iframe style={{ width: '375px', height: '667px' }} src="/preview"></iframe>
</div>
```
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 (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Preview config={config}></Preview>
</div>
);
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 (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Preview config={config}></Preview>
</div>
);
}
export default PreviewPage;
```
For the API section, refer to API
src/pages/iframe/index.tsx
```js
function IframePage() {
return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<iframe
style={{ width: '375px', height: '667px' }}
src="/preview"
></iframe>
</div>
);
}
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.

View File

@@ -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<UserConfig>(config);
config.i18n = false;
export default function Layout({ children }: IRouteComponentProps) {
return (
<configContext.Provider value={config}>{children}</configContext.Provider>
);
}
```
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: <PlayCircleOutlined />,
displayName: '按钮',
urlFn: () => import('./button'),
},
];
export const defaultConfig: Partial<InitConfig> = {
leftAllRegistMap: LeftRegistMap,
leftRenderListCategory: [
{
type: 'basic',
icon: <HighlightOutlined />,
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 <Button>测试</Button>;
},
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 (
<div {...innerContainerDragUp(config)}>
<div style={{ height: HeaderHeight }}>
head
<button
onClick={() => {
window.open('/iframe');
}}
>
go preview
</button>
</div>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: `calc(100vh - ${HeaderHeight})`,
width: '100vw',
}}
>
<div style={{ height: '100%' }}>
<LeftConfig config={config}></LeftConfig>
</div>
const everyFn = () => {};
const subscribeFn = useCallback(() => {
localStorage.setItem(PREVIEWSTATE, JSON.stringify(config.getStore().getData()));
}, [config]);
const [state] = useStoreState(config, subscribeFn, everyFn);
return (
<div {...innerContainerDragUp(config)}>
<div style={{ height: HeaderHeight }}>
head
<button
onClick={() => {
window.open('/iframe');
}}
>
go preview
</button>
<button
onClick={() => {
window.open('/preview');
}}
>
go preview
</button>
</div>
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: `calc(100vh - ${HeaderHeight})`,
width: '100vw',
}}
>
<div style={{ height: '100%' }}>
<LeftConfig config={config}></LeftConfig>
</div>
<ContainerWrapper config={config}>
<>
<Control
config={config}
style={{ position: 'fixed', bottom: '60px', right: '450px', zIndex: 100 }}
></Control>
<Container state={state} config={config} context="edit"></Container>
</>
</ContainerWrapper>
<div className="rightrender" style={{ height: '100%' }}>
<RightConfig state={state} config={config}></RightConfig>
</div>
</div>
</div>
);
<ContainerWrapper config={config}>
<>
<Control
config={config}
style={{
position: 'fixed',
bottom: '60px',
right: '450px',
zIndex: 100,
}}
></Control>
<Container state={state} config={config} context="edit"></Container>
</>
</ContainerWrapper>
<div className="rightrender" style={{ height: '100%' }}>
<RightConfig state={state} config={config}></RightConfig>
</div>
</div>
</div>
);
}
```
此时启动项目,可以看见编辑器已经显示出来了。拖动组件时,也能正确置入画布。
src的pages下新增对应的页面
预览时preview套iframe:
```html
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<iframe style={{ width: '375px', height: '667px' }} src="/preview"></iframe>
</div>
```
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 (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Preview config={config}></Preview>
</div>
);
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 (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Preview config={config}></Preview>
</div>
);
}
export default PreviewPage;
```
有关 api 部分请参考 api
src/pages/iframe/index.tsx
```js
function IframePage() {
return (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<iframe
style={{ width: '375px', height: '667px' }}
src="/preview"
></iframe>
</div>
);
}
export default IframePage;
```
此时拖拽组件进入画布后,点击按钮进入预览则可看见预览状态也被渲染出来了。

View File

@@ -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
-->
<!DOCTYPE html>
@@ -10,7 +10,7 @@
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;">
<title>Dooringx-example</title>
<meta name="description" content="DooringX是一款功能强大开源免费的H5可视化页面搭建框架致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。">
<meta name="keywords" content="H5,H5制作网站,H5在线制作页面,HTML5,javascript,react,nodejs,前端开发,github,开源">

View File

@@ -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';

View File

@@ -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 (
<Button
style={{

View File

@@ -1,5 +1,5 @@
{
"version": "0.15.0",
"version": "0.15.1",
"license": "MIT",
"main": "dist/index.js",
"module": "dist/dooringx-lib.esm.js",

View File

@@ -0,0 +1,30 @@
/*
* @Author: yehuozhili
* @Date: 2022-04-27 22:15:24
* @LastEditors: yehuozhili
* @LastEditTime: 2022-04-27 22:38:59
* @FilePath: \dooringx\packages\dooringx-lib\src\hooks\useRegistFunc.ts
*/
import { useEffect } from 'react';
/**
*
*
* @export 用于简化注册函数代码
* @param {boolean} dep 配置的开关
* @param {('preview' | 'edit')} context 传递的环境变量
* @param {Function} registFn 注册的函数
*/
export function useRegistFunc(dep: boolean, context: 'preview' | 'edit', registFn: Function) {
useEffect(() => {
let unRegist: Function = () => {};
if (dep) {
unRegist = registFn;
}
return () => {
if (context === 'preview') {
unRegist(); // 必须在预览时注销,否则影响二次点击效果,不在预览注销影响编辑时跨弹窗
}
};
}, [context, dep, registFn]);
}

View File

@@ -2,7 +2,7 @@
* @Author: yehuozhili
* @Date: 2021-03-14 04:22:18
* @LastEditors: yehuozhili
* @LastEditTime: 2022-04-23 23:02:04
* @LastEditTime: 2022-04-27 22:45:42
* @FilePath: \dooringx\packages\dooringx-lib\src\index.tsx
*/
@@ -53,6 +53,9 @@ export { changeUserValue } from './core/utils/index';
// 用于制作快捷键
export { CommanderItemFactory } from './core/command/abstract';
// 用于制作函数
export { useRegistFunc } from './hooks/useRegistFunc';
export { defaultStore } from './config';
//state
export { focusState } from './core/focusHandler/state';

View File

@@ -1,6 +1,6 @@
{
"name": "dooringx-plugin-template",
"version": "0.15.0",
"version": "0.15.1",
"description": "> TODO: description",
"author": "yehuozhili <673632758@qq.com>",
"homepage": "https://github.com/H5-Dooring/dooringx#readme",

View File

@@ -40,7 +40,7 @@
"@rollup/plugin-node-resolve": "^13.0.4",
"@rollup/plugin-url": "^6.1.0",
"@svgr/rollup": "^5.5.0",
"dooringx-lib": "^0.15.0",
"dooringx-lib": "^0.15.1",
"postcss": "^8.3.6",
"rollup-plugin-peer-deps-external": "^2.2.4",
"rollup-plugin-postcss": "^4.0.1",