H5-Dooring is a powerful, open source and free H5 visual page configuration solution, committed to providing a set of simple, convenient, professional and reliable H5 landing page best practices that are easy to use, professional and reliable, and infinitely possible. The technology stack is mainly react, and the background is developed using nodejs.
Contributions, issues and feature requests are welcome!
Feel free to check issues page.
Give a ️ if this project helped you!
The visual editor mainly consists of the following parts:
We can use react-dnd and react-draggable , which is popular in the community. Since our canvas is drag-dragable and zoomed in, we need to empower the canvas here. For specific implementations, please refer to the following.
The second is the H5 editor part, which is the core function, which we will analyze in detail later. There are also functions such as preview, generating preview links, saving json files, and saving templates. These functions are essentially operations on our json files, but they are one of the common methods of visual construction technology at present. Let’s take a look at the demo of these features:
Our h5 page visual editor uses UMI as a scaffolding tool.
Umi is a scalable enterprise-level front-end application framework, based on routing, and supports both configured routing and convention routing to ensure that the routing functions are complete and function expansion is performed. Then it is equipped with a plug-in system with a complete life cycle, covering every life cycle from source code to build products, supporting various functional expansion and business requirements.
In this way, we will not pay attention to the cumbersome project configuration details. We can directly use antd and less solutions in the project, and integrate the currently popular css module , which can facilitate us to modularly develop css in the project. The specific usage process of UMI's project creation is as follows:
// 创建并进入工程目录
mkdir dooring && cd dooring
// 创建umi应用
yarn create @ umijs / umi - app
// 安装依赖
yarn // 或者使用npm installA simple three-step strategy can easily build our project, does it save a lot of trouble? (Before using these methods, we first make sure that our local node version is 10.13 or above)
After the project is created, we also need to install the necessary third-party components in visualization. After investigating the selected components of the community, I adopted the following solution:
You can install the above components yourself before running the project.
After the best project development preparation, we will start designing our h5 page visual editor - Dooring .
The H5 visual editor mainly requires 4 parts, which have been analyzed at the beginning of the article. Here we use a diagram to consolidate it: The above is the most basic and core functional display model, and we will dismantle it one by one and implement it one by one.
We all know that there are several popular page visualization solutions:
The author made a comparison chart of advantages and disadvantages, as follows:
| plan | Customization degree | shortcoming |
|---|---|---|
| Edit code online | Highest | High cost of use, unfriendly to non-technical personnel, and low efficiency |
| Edit json online | Higher | Need to be familiar with json, has a certain cost of use, is not friendly to non-technical personnel, and is generally efficient |
| No code drag and drop implementation | high | Low cost of use, basically no threshold for operation, high efficiency |
According to the above analysis, in order to develop a visual editor that is low-threshold and suitable for anyone, the author will adopt the third solution to implement it. There are many products on the market, such as Yiqixiu, Tuzhan, Baidu H5, etc. The implementation principle is actually based on json. We convert the pages we configured into json data through visualization, and finally dynamically generate the H5 site based on the json renderer .
In order to provide the customization capabilities of components, we need to define a set of highly available data structures to achieve the maintenance advantages brought about by changes in component requirements.
Before starting to design the data structure, let’s first disassemble the module: different components correspond to different "edit areas". We need to design a unified standard configuration to agree on it, which is also very beneficial for the design of the form editor. The specific disassembly is as follows:
After the above analysis, the author designed a data structure similar to the following:
"Text" : {
"editData" : [
{
"key" : "text" ,
"name" : "文字" ,
"type" : "Text"
} ,
{
"key" : "color" ,
"name" : "标题颜色" ,
"type" : "Color"
} ,
{
"key" : "fontSize" ,
"name" : "字体大小" ,
"type" : "Number"
} ,
{
"key" : "align" ,
"name" : "对齐方式" ,
"type" : "Select" ,
"range" : [
{
"key" : "left" ,
"text" : "左对齐"
} ,
{
"key" : "center" ,
"text" : "居中对齐"
} ,
{
"key" : "right" ,
"text" : "右对齐"
}
]
} ,
{
"key" : "lineHeight" ,
"name" : "行高" ,
"type" : "Number"
}
] ,
"config" : {
"text" : "我是文本" ,
"color" : "rgba(60,60,60,1)" ,
"fontSize" : 18 ,
"align" : "center" ,
"lineHeight" : 2
}
}After this standardized structural design, we can easily implement the functions of editing pages we need, and the later expansion is very convenient. You only need to add configuration to editData. As for the implementation of the dynamic form editor, there are many solutions. The author has written related articles before, so I will not introduce them in detail here.
Build a general form management configuration platform based on react (same as vue)
An important issue in the design of component library is the size and rendering issues. Once the component library becomes more and more, it means that the page loading will be very slow, so we need to implement the ability to load components and code segmentation asynchronously. Umi provides such functions, and we can implement our own on-demand components based on the API it provides.
import { dynamic } from 'umi' ;
export default dynamic ( {
loader : async function ( ) {
// 这里的注释 webpackChunkName 可以指导 webpack 将该组件 HugeA 以这个名字单独拆出去
const { default : HugeA } = await import ( /* webpackChunkName: "external_A" */ './HugeA' ) ;
return HugeA ;
} ,
} ) ;Through the above method, we define each component that wraps each of our components, so that we can load on demand, but the best suggestion is that we do not need to load and unpack each component on demand. For the title , notification bar , header , and footer components, we can completely put it in a group. This will not only not affect the loading speed, but also reduce certain http requests.
Here I will give you a brief example of component implementation, which is convenient for everyone to understand:
const Header = memo ( ( props ) => {
const {
bgColor ,
logo ,
logoText ,
fontSize ,
color
} = props
return < header className = { styles . header } style = { { backgroundColor : bgColor } } >
< div className = { styles . logo } >
< img src = { logo && logo [ 0 ] . url } alt = { logoText } />
</ div >
< div className = { styles . title } style = { { fontSize , color } } > { logoText } </ div >
</ header >
} )The props attribute of the header component above is completely defined by the json structure we designed before. During the user editing process, the receipt will be collected and passed to the header component. The last step is to dynamically pass these components to dynamic components. This is also introduced above. You can make dynamic rendering based on your own implementation.
The preview function is relatively simple. We only need to throw the user-generated json data into the H5 renderer. Here we need to make a rendering page to preview the components separately. Let’s take a look at a few preview effects: The previous renderer principle has been introduced, so I won’t introduce it one by one here. Those who are interested can communicate and discuss it.
To download this online, we need to use an open source library: file-saver , which specifically solves the dilemma of difficulty in front-end downloading files. Specific use examples:
var FileSaver = require ( 'file-saver' ) ;
var blob = new Blob ( [ "Hello, world!" ] , { type : "text/plain;charset=utf-8" } ) ;
FileSaver . saveAs ( blob , "hello world.txt" ) ;The above code can download the incoming data into a txt file. If it is a Blob, can you still download pictures online and html? The answer is yes, so our download task adopts this solution.
Since the backend part involves a lot of knowledge points and is not the focus of this article, I will give a few points here. You can use completely different technologies to implement backend services, such as PHP , Java , Python or Egg . The author uses koa here. The main implementation functions are as follows:
For specific code, please refer to another full stack development article by me.
Implement a CMS full-stack project from 0 to 1 based on nodeJS
The pattern is basically the same.
git clone https://github.com/MrXujiang/h5-Dooring.git cd ./h5-Dooringyarn installStart the application
yarn run startUpgrading version 1.3, please stay tuned...