craft.js的一个记录,体验拖拽式生成网站,写一个简单的demo
1、craft简介
Craft.js通过模块化页面编辑器的构建模块来解决此问题。它提供了拖放系统,并处理了应呈现,更新和移动用户组件的方式。
官网:https://craft.js.org/
2、demo简介
由于craft.js目前才0.1.0-beta.17
版本,国内没啥资料,记录一下简单demo的实现,可以快速入门
3、创建项目
项目是使用react
,UI框架官方推荐的是material-ui
,但是我这里用的是ant design
npx create-react-app mydemo
直接放项目依赖,可能后续版本不一致
"dependencies": {
"@craftjs/core": "^0.1.0-beta.17",
"@material-ui/core": "^4.11.4",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"antd": "^4.15.5",
"material-ui-color-picker": "^3.5.1",
"react": "^17.0.2",
"react-contenteditable": "^3.3.5",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"web-vitals": "^1.0.1"
}
把依赖性放到配置文件里面,安装就好了。
npm install
或者使用yarn
,都一样
然后把src/app.js
里面的都删掉
import './App.css';
function App() {
return (
<div className="App">
</div>
);
}
export default App;
然后引入需要的依赖
import React from 'react';
import { Row, Col } from 'antd';
import './App.css';
import { Editor, Frame, Element } from "@craftjs/core";
function App() {
return (
<div className="App">
<Row>
<Col span={16} className="leftBox">
</Col>
<Col span={8} className="toolBox">
<div>这里放工具栏</div>
</Col>
</Row>
</div>
);
}
export default App;
修改index.css
,把App.css
里面的都删了,不删也行,只不过我想删。
@import '~antd/dist/antd.css';
.leftBox {
border: 1px solid #ccc;
}
.header {
border-bottom: 1px solid #ccc;
}
.container {
background: #ccc;
border: 1px solid rgb(32, 32, 32);
margin: 10px 0;
min-height: 40px;
padding: 10px;
}
.toolBox {
padding-left: 20px;
}
4、创建Button模块
因为是基于模块开发的,所以要把各个组件都抽离成模块, 项目中一共没用到几个模块,先写一个Button
的
创建src/conponents/Button.jsx
import React from "react";
import { useNode } from "@craftjs/core";
import { Button } from 'antd';
export const MyButton = (props) => {
const { connectors: { connect, drag } } = useNode();
const { text } = props;
return (
// 说这个组件是可以拖动的
<Button ref={ref => connect(drag(ref))} >
{text}
</Button>
)
}
// 给按钮的默认配置,如果不传就走的这个参数,默认文字为`按钮`
export const ButtonDefaultProps = {
text: '按钮',
};
MyButton.craft = {
props: ButtonDefaultProps
}
然后在入口app.js
引入
import React from 'react';
import { Row, Col } from 'antd';
import './App.css';
import { Editor, Frame, Element } from "@craftjs/core";
import {MyButton} from './conponents/Button'
function App() {
return (
<div className="App">
{/* 这是编辑器的区域,resolve人里面是会用到的组件,需要在这里申明一下 */}
<Editor resolver=>
<Row>
<Col span={16} className="leftBox">
{/* 编辑区域需要包裹在这个元素里面 */}
<Frame>
{/* 生成一个div元素,是一个canvas节点,可以编辑*/}
<Element is='div' canvas style=>
<MyButton text="默认的"></MyButton>
<MyButton text="默认的2"></MyButton>
</Element>
</Frame>
</Col>
<Col span={8} className="toolBox">
<div>这里放工具栏</div>
</Col>
</Row>
</Editor>
</div>
);
}
export default App;
这个时候运行就会发现界面上多了俩按钮,然后就可以拖动这俩按钮交换位置了。
5、创建Container组件
这个组件具体用法可以参考官网https://craft.js.org/r/docs/concepts/user-components#connectors
就是定义一个区域,可以进行编辑
创建src/conponents/Container.jsx
import React from "react";
import { Element, useNode } from "@craftjs/core";
import {Text} from './Text'
export const Container = ({ children }) => {
const { connectors: { connect, drag } } = useNode();
return (
<div ref={ref => connect(drag(ref))} className='container'>
{children}
</div>
)
}
这个我为了看的到效果,在前面有提前定义好样式,然后在app.js
里面引入
// 这加了新添加的东西
import { Container } from './conponents/Container';
function App() {
return (
<div className="App">
<Editor resolver=>
<Row>
<Col span={16} className="leftBox">
<Frame>
{/* 多大的 */}
<Element is='div' canvas style=>
{/*...之前的东西*/}
<Container>
<MyButton text="Container里面的按钮"></MyButton>
</Container>
</Element>
</Frame>
</Col>
</Row>
</Editor>
</div>
);
}
这样就可以看到有一个灰色的区域了,不过这个组件一般都是用来拖拽生成一个区域,然后里面进行编辑的,我们写拖拽工具插件
6、创建Toolbox模块
创建src/conponents/Toolbox.jsx
import React from "react";
import { Element, useEditor } from "@craftjs/core";
import { Container } from "./Container";
import { Row, Col, Button } from 'antd';
import { MyButton } from './Button'
export const Toolbox = () => {
const { connectors, query } = useEditor();
return (
<Row container>
<Col span={24} container direction="column" >
<Button ref={ref => connectors.create(ref, <MyButton text="拖拽生成的按钮"/>)}>Button</Button>
</Col>
<Col span={24} container direction="column" >
{/* 注意Container这里:是创建一个element标签,然后表示为Container元素,然后是个canvas节点 这样的才可以进行编辑*/}
<Button ref={ref => connectors.create(ref, <Element is={Container} padding={20} canvas />)} >Container</Button>
</Col>
</Row>
)
};
然后app.js
引入
import { Toolbox } from './conponents/Toolbox'
<Editor resolver=>
<Col span={8} className="toolBox">
<div>这里放工具栏</div>
<Toolbox></Toolbox>
</Col>
</Editor>
然后就可以拖拽使用了
7、总结
没有写一些文档类型的东西,没有写一些定义之类的东西,因为文档全英文,自己翻译不准,然后具体也没有很明白,只是简单记录一下使用方法,给入个门,最起码可以跑通,然后操作起来,具体扩展就靠自行探索了,最基本的东西就这些,其他更深层次的功能,比如layer
待我弄明白再写一篇。