页面编辑是提供优秀用户体验的好方法. 然而,建造一个往往是一个相当可怕的任务.
已有的库会带出一个完整的工作页编辑器出框,并带有用户界面和可编辑组件. 然而,如果您想要做自定义,比如修改用户界面及其行为,那么最肯定的就是修改库本身.
Craft.js通过模块化页面编辑器的构件来解决这个问题. 它携带拖放系统,处理用户组件的提供、更新和移动方式,等等。 有了这个,你就能建立自己的页面编辑器 确切地说,你希望它看起来和行为.
文档
实例
这些例子应该可以让你了解Craft.js的灵活性.
这两个例子看起来彼此非常不同,UI也非常不同. 但他们都是手工业者
特征: 火:
只是反应
不需要复杂的插件系统 。 从上到下设计您的编辑器的方式与您在React中设计其他前端应用程序的方式相同.
简单的用户组件很容易被定义为:
import { useNode } from "@craftjs/core";
const TextComponent = ({ text }) => {
const {
connectors: { connect, drag },
} = useNode();
return (
<div ref={(ref) => connect(drag(ref))}>
<h2>{text}</h2>
</div>
);
};
你页面编辑器的整个UI都是用反应构建的.
import React from "react";
import { Editor, Frame, Element } from "@craftjs/core";
const App = () => {
return (
<div>
<header>Some fancy header or whatever</header>
<Editor>
// Editable area starts here
<Frame resolver={{ TextComponent, Container }}>
<Element canvas is={TextComponent} text="I'm already rendered here" />
</Frame>
</Editor>
</div>
);
};
控制您组件的编辑方式
对页面编辑器的一个明显要求是,它们需要允许用户编辑组件. Craft.js 中,您控制这些组件的编辑过程 .
在下面的例子中,当用户点击一个组件时,我们将显示一种模式,要求用户输入该组件的值 text 道具 (英语). 随着输入值的改变,该组件会用更新道具重新发回.
import { useNode } from "@craftjs/core";
const TextComponent = ({ text }) => {
const {
connectors: { connect, drag },
isClicked,
actions: { setProp },
} = useNode((state) => ({
isClicked: state.events.selected,
}));
return (
<div ref={(dom) => connect(drag(dom))}>
<h2>{text}</h2>
{isClicked ? (
<Modal>
<input
type="text"
value={text}
onChange={(e) => setProp(e.target.value)}
/>
</Modal>
) : null}
</div>
);
};
有了这个功能,您可以轻松地执行内容可编辑的文本或拖放到大小的组件,就像任何现代的页面编辑器一样.
有可下降区域的用户组件
假设我们需要一个"容器"组件,用户可以掉入编辑器. 此外,我们还希望它们能够把其他部件拖入集装箱.
在Craft.js语中,它和叫作 <Canvas />
import {useNode} from "@craftjs/core";
const Container = () => {
const { connectors: {drag} } = useNode();
return (
<div ref={drag}>
<Canvas id="drop_section">
// Now users will be able to drag/drop components into this section
<TextComponent />
</Canvas>
</div>
)
}
广泛
Craft.js提供一种表达式的API,可以方便地读取并操纵编辑器状态. 假设您想要执行一个组件的复制功能:
import {useEditor, useNode} from "@craftjs/core";
const Container = () => {
const { actions: {add}, query: { createNode, node } } = useEditor();
const { id, connectors: {drag, connect} } = useNode();
return (
<div ref={dom => connect(drag(dom))}>
...
<a onClick={() => {
const { data: {type, props}} = node(id).get();
add(
createNode(React.createElement(type, props));
);
}}>
Make a copy of me
</a>
</div>
)
}
序列状态
编辑器的状态可以被序列化为JSON,然后可以应用你选择的压缩技术来存储.
const SaveButton = () => {
const { query } = useEditor();
return <a onClick={() => console.log(query.serialize()) }>Get JSON</a>
}
当然,Craft.js也能从JSON字符串中再现出整个状态.
const App = () => {
const jsonString = /* retrieve JSON from server */
return (
<Editor>
<Frame json={jsonString}>
...
</Frame>
</Editor>
)
}
这是谁的
你应该用这个,如果:
- 您想要按照您自己的UI 规格设计您的页面编辑器 。 有了Craft.js,你几乎控制了页面编辑器的外观和感觉的每一个方面.
- 你喜欢反应生态系统 作为一个反应框架,你不仅可以公开地构建自己的用户界面,还可以扩展到数千个用于页面编辑器的现有反应组件.
- 你是班上最酷的小孩
您不应使用此选项 :
- 你需要一个在盒子里工作的页面编辑器 craft.js是一个抽象的,您可以执行自己的页面编辑器。 例如,它没有现成的用户界面.
- 不过,你还可以考虑使用 实例 作为起点.
附加套件: tada :
- @ craftjs/ layers (英语) 类似相机的层面板
致谢:升起的手:
- 反应-dnd React 拖放库 . 虽然它实际上没有在这里使用,但Craft.js的许多方面都是用反应-dnd来写作,作为参考,同时还借用了一些公用事业和功能.
- Grape.js (英语) HTML网络构建器框架. 这为Craft.js提供了灵感。 Craft.js中使用的元素定位逻辑取自Grape.js
- 使用方法 处理减员时的超手钩. craft.js使用稍作修改的版本
use-methods更适合我们的API.
获取帮助: wave :
如果你有问题,或者有事情想讨论(例如:贡献),请到我们那里去 解析器 服务器.
赞助商:心 装饰:
Craft.js 现根据 麻省理工学院许可证 以百分百的爱建造 如果您认为它有用并愿意确保它的持续发展,请考虑成为支持者/赞助者,或通过下列途径一次性捐款: Github 发起人, (中文(简体) ), 开放集体 或者说 高飞。 。 。 .