2021-11-24 12:50:19 +08:00
|
|
|
|
---
|
2021-11-25 12:15:19 +08:00
|
|
|
|
title: 介绍
|
2021-11-24 12:50:19 +08:00
|
|
|
|
toc: menu
|
2021-11-25 12:15:19 +08:00
|
|
|
|
order: 1
|
2021-11-24 12:50:19 +08:00
|
|
|
|
nav:
|
|
|
|
|
title: 指南
|
|
|
|
|
order: 1
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### dooringx-lib 是什么?
|
|
|
|
|
|
|
|
|
|
dooringx-lib 是 dooringx 的基座,是移除了 dooringx 插件的可视化拖拽框架。
|
|
|
|
|
|
|
|
|
|
dooringx-lib 提供自己的一套数据流事件机制以及弹窗等解决方案,可以让你更快地自己定制开发可视化拖拽平台。
|
|
|
|
|
|
2022-09-02 18:06:26 +08:00
|
|
|
|
区别于别的搭建平台,其较为适合制作移动端,主要是绝对定位搭建而非静态定位搭建,绝对定位的拖拽较为方便运营人员理解。
|
|
|
|
|
|
2021-11-24 12:50:19 +08:00
|
|
|
|
### dooringx-lib 如何工作?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dooringx-lib 在运行时维护一套数据流,主要分为json数据部分,左侧组件部分,右侧配置项部分,快捷键部分,弹窗部分,事件与函数部分,数据源部分。
|
|
|
|
|
|
|
|
|
|
其除了提供基础的拖拽、移动、缩放、全选、旋转等功能外,还可以使用暴露的组件。如果觉得组件不够定制化,可以调整样式或者自己重新写。
|
|
|
|
|
|
2022-09-02 18:06:26 +08:00
|
|
|
|
### 数据流转是怎样的?
|
|
|
|
|
|
|
|
|
|
1、页面上渲染主要围绕store中json制作,你可以在任何地方通过`config.getStore().getData()`拿到store数据,修改后使用`config.setData()`设置数据。
|
|
|
|
|
|
|
|
|
|
2、右侧配置项的开发本质也是通过修改json完成。
|
|
|
|
|
|
|
|
|
|
3、事件流设计:每个组件可以抛出任意个函数,组件中可以设置时机,比如设置点击组件a按钮或b按钮为触发时机,触发后调用事件链。事件链可以设置由多个组件抛出的函数链接而成。
|
|
|
|
|
|
2021-11-24 12:50:19 +08:00
|
|
|
|
|
|
|
|
|
### 快速上手
|
|
|
|
|
|
2022-04-28 00:33:36 +08:00
|
|
|
|
首先创建个文件夹,例如dooringx-example。
|
2021-11-24 12:50:19 +08:00
|
|
|
|
|
2022-04-28 00:33:36 +08:00
|
|
|
|
我们推荐使用Umi脚手架快速搭建我们的项目。
|
|
|
|
|
|
|
|
|
|
在文件夹内使用命令`yarn create @umijs/umi-app `或` npx @umijs/create-umi-app`
|
|
|
|
|
|
|
|
|
|
安装dooringx-lib:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
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;
|
2021-11-24 12:50:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2022-04-28 00:33:36 +08:00
|
|
|
|
在src/pages/index.tsx处新增编辑器代码:
|
2021-11-24 12:50:19 +08:00
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
import {
|
2022-04-28 00:33:36 +08:00
|
|
|
|
RightConfig,
|
|
|
|
|
Container,
|
|
|
|
|
useStoreState,
|
|
|
|
|
innerContainerDragUp,
|
|
|
|
|
LeftConfig,
|
|
|
|
|
ContainerWrapper,
|
|
|
|
|
Control,
|
2021-11-24 12:50:19 +08:00
|
|
|
|
} from 'dooringx-lib';
|
|
|
|
|
import { useContext } from 'react';
|
|
|
|
|
import { configContext } from '@/layouts';
|
|
|
|
|
import { useCallback } from 'react';
|
|
|
|
|
export const HeaderHeight = '40px';
|
|
|
|
|
export default function IndexPage() {
|
2022-04-28 00:33:36 +08:00
|
|
|
|
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>
|
|
|
|
|
);
|
2021-11-24 12:50:19 +08:00
|
|
|
|
}
|
|
|
|
|
```
|
2022-04-28 00:33:36 +08:00
|
|
|
|
此时启动项目,可以看见编辑器已经显示出来了。拖动组件时,也能正确置入画布。
|
2021-11-24 12:50:19 +08:00
|
|
|
|
|
2022-04-28 00:33:36 +08:00
|
|
|
|
src的pages下新增对应的页面:
|
2021-11-24 12:50:19 +08:00
|
|
|
|
|
2022-04-28 00:33:36 +08:00
|
|
|
|
src/pages/preview/index.tsx
|
2021-11-24 12:50:19 +08:00
|
|
|
|
```js
|
2022-04-28 00:33:36 +08:00
|
|
|
|
import { configContext } from '@/layouts';
|
|
|
|
|
import { Preview } from 'dooringx-lib';
|
|
|
|
|
import { useContext } from 'react';
|
2021-11-24 12:50:19 +08:00
|
|
|
|
|
|
|
|
|
function PreviewPage() {
|
2022-04-28 00:33:36 +08:00
|
|
|
|
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>
|
|
|
|
|
);
|
2021-11-24 12:50:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default PreviewPage;
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2022-04-28 00:33:36 +08:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
此时拖拽组件进入画布后,点击按钮进入预览则可看见预览状态也被渲染出来了。
|
2022-09-02 18:06:26 +08:00
|
|
|
|
|
|
|
|
|
|