background

In recent years, low code, no code, pro code and more and more appear in our field of vision. With the mindset of not being caught up 🐶, I decided to explore further.

I’m in the Marketing Department. Every day/month is loaded with a large number of marketing activities, and this article is also a few of my experiences in the process of exploring visual building

In fact, these nouns are all related to construction. One of the most widely used scenarios is marketing. We know that whether it is e-commerce giants like Taobao and Jingdong, or OTA like Ctrip and Qunar, there are countless activity pages on APP every day.

Roughly combing some characteristics of marketing activities:

  • Pages are similar: The page layout and business logic are fixed
  • High frequency of demand: multiple requests per week or even daily
  • Fast iteration: short development time, tight launch time
  • Development time: Repeated development tasks consume communication time and manpower of all parties

Different from the conventional business development, marketing activities are often affected by many factors: the promotion of holidays, policies and rules, so often may be said this morning, tomorrow will be on this kind of activity. If only rely on front-end students to maintain, that is not to add countless classes (such as my previous 😭)

Each time to a new activity, rely on the front end of the students to draw the page, obviously this efficiency is very low. If the schedule is generous, if you meet 618, double 11 afraid is not to drive us crazy.

Floor structures,

Given this scenario, there was a lot of internal discussion. The consistent conclusion is that the development students provide marketing and build the background, the page can be configured, and the configuration work is handed over to the product/operation students. In this way, the plan of building marketing page based on floor arises at the historic moment.

Actually,Floor structures,In the marketing page is a common way to build.



The above picture shows an activity page of Jingdong, which is mainly composed of three parts: the floor of the first picture, the floor of coupons and the floor of hot sellers. Because just like the building in life, so in the early marketing building, there isfloorThe concept of. Each floor corresponds to a specific component.



And then on the specific floorEdit contentThe region can then upload the corresponding data.

But this approach has one big drawback: it’s not intuitive. With the rapid iteration of the business, some feedback has also been obtained. It turns out that what the operation students really need is something that can directly drag and drop pages to generate, that is, visual scaffold

Visual Construction

On the basis of floor construction, it was further transformed into a visual construction, which increased a lot of complexity. Simply to see the different rendering of the page, may just add a drag and drop operation. But when I was really ready to go to the ground, I found that there were a lot of details, including a lot of design concepts.

Let’s take a look at the prototype diagram and then take a closer look at what needs to be done:



Most marketing visualization systems on the market are basically presented on pages like the one above. The left corresponds to the component area, the middle is the canvas area, and the right is the properties area.

Drag the component on the left to the canvas in the middle, select the component, and the properties panel on the right displays the properties associated with that component. Edit the property on the right, and the corresponding component styles in the canvas are updated synchronously. The page splicing is completed. You can preview the page through the operation similar to preview. Preview is correct, you can release the activity through the publish button.

After the process is sorted out, let’s look at the infrastructure of the project:

Here I have paved the functional design of the project based on the prototype. In fact, it still revolves around components, canvas, and properties panel.

Here, let’s think about a few questions:

  • How does the Canvas area render the components that have been added to the canvas (the component library has many components, the canvas may only need to add a few components, consider how to do dynamic rendering)?
  • Drag a component from the left into the canvas area, select the component, and see the properties associated with the component. How is the component Schema designed?
  • Can the rendering of the Canvas area and the component at preview use the same rendering logic?
  • How the component’s data is maintained (consider adding components, removing components, rendering/previewing components, etc.)
  • How the component library is maintained (consider scenarios where new components meet business needs)

Let’s start with the first one, which is simply dynamic loading of components.

Dynamically loaded component

If you use Vue a lot, I’m sure you’re familiar with dynamic components in Vue:

<! >< component :is="currentView"></component>

Most of the editors on the market also take advantage of this feature. The idea is as follows:

  • I’m going to take an arraycomponentDataMaintain the data in the editor
  • Drag the data for a component when it is dropped onto the canvaspushInto thecomponentData
  • Editor traversal (v-for) component datacomponentDataRender the components to the canvas in turn

Since my team and myself use React all the time, I will highlight the implementation of dynamic loading of React components. The framework uses Umi.

When I was implementing this part of the functionumitheapiFound in thedynamic:



Encapsulate an asynchronous component:

const DynamicComponent = (type, componentsType) => { return dynamic({ loader: async function () { const { default: Component } = await import( `@/libs/${componentsType}/${type}` ); return (props) => { return <Component {... props} />; }; }}); };

Then, when invoked, pass in an array of components:

const Editor = memo((props) => { const { componentData, } = props; return ( <div> {componentData.map((value) => ( <div key={value.id} > <DynamicComponent {... value} /> </div> ))} </div> ); });

Having solved the first question, let’s move on to the second question, which is: how should the component Schema be designed?

Component Schema Design

This involves the linkage of components, canvases and property areas. It mainly contains form properties that are strongly related to the component, as well as initial values.

Because of the field constraints and validation involved in component properties, it is recommended that the project use TS for specification and error avoidance

Here, take a TabList component as an example to show its Schema structure:

Const TabList = {formData: [{key: 'tabs', name: 'tableList ', type:' tableList ',}, {key: 'layout', name: 'tableList ', type:' tableList ', type: 'Select' options: [{key: 'single' text: 'single'}, {key: 'double', the text: 'double row,},],}, {key:' activeColor 'name: 'active Color, type:' Color ',}, {key: 'Color', name: 'text Color, type:' Color '}, {key: 'fontSize, name:' text size, type: 'Number',},], initialData: {tabs: [{id: uuid(6), title: 'NULL ', list: [{id: uuid ', goCity:' NULL ', backCity:], initialData: {tabs: [{id: uuid(6), title: 'NULL ', list: [{id: uuid ', goCity:' NULL ', backCity: 'Beijing ', goDate: '08-18', goWeek:' Wednesday ', airline: 'China United Airlines ', price: 357, disCount: '4',},],},], layout: 'single', color: 'rgba (153153153, 1), activeColor:' rgba (0102204, 1), fontSize: 16,,}};

The structure is agreed upon when the component is initialized, and when the component is dropped into the canvas area, we get the currently selected component data, and the properties panel on the right renders the corresponding editable form item. Take a look at the code in the form area on the right:

const FormEditor = (props) => { const { formData, defaultValue } = props; console.log('FormEditor props', props); const [form] = Form.useForm(); Const HandleFormChange = () = bb0 {console.log(' form update ',form.getFieldsValue()); }; return ( <Form form={form} initialValues={defaultValue} onValuesChange={handleFormChange} > {formData.map((item, i) => { return ( <React.Fragment key={i}> {item.type === 'Number' && ( <Form.Item label={item.name} name={item.key}> <InputNumber max={item.range && item.range[1]} /> </Form.Item> )} {item.type === 'Text' && ( <Form.Item label={item.name} name={item.key}> <Input /> </Form.Item> )} {item.type === 'TitleList' && ( <Form.Item label={item.name} name={item.key}> <TitleList /> </Form.Item> )} {item.type === 'Select' && ( <Form.Item } name={item.key} bb0 <Select table1 {item.option. map((v: any, I: number) => { return ( <Option value={v.key} key={i}> {v.text} </Option> ); })} </Select> </Form.Item> )} </React.Fragment> ); })} </Form> ); };

OnValuesChange is triggered when a specific form item in the form area changes, which is a callback event that is triggered when the field value of the Ant Design form is updated. The data is then updated to the store. And the data source of the canvas is the componentData in the store and the page will be updated in real time. Take a look at the overall data flow graph:



This solves the second problem.

Let’s move on to the third question: can we use the same rendering logic for the canvas area and the component at preview time?

Component sharing

We can think of the preview component as either the static version or the snapshot version of the canvas area. From the perspective of page rendering, there is not much difference, so from the perspective of code design, the two parts can of course share a component. We call this shared component RenderComponent. TSX, the data source is ComponentData in Store, and then we combine with DynamicComponent to get the following code:

const RenderComponent = memo((props) => { const { componentData, } = props; return ( <> {componentData.map((value) => ( <div key={value.id} > <DynamicComponent {... value} /> </div> ))} </> ); });

Data storage/distribution

As for the fourth question: how to maintain the data of a component (consider adding a component, removing a component, rendering/preview of a component, etc.), I have already mentioned it in the second question above. There is a store maintained globally:

{// CurComponent :[]; // CurComponent :[]; {// AddComponentData (){// AddComponentData (){// AddComponentData (){// AddComponentData (); // Delete Component (){// Delete Component (){// Delete Component (){}}

For a large front-end project such as a visual editor, a global state management mechanism is required for data storage and distribution. This is also helpful for data state sharing and synchronization.

Component development/maintenance

Let’s look at the last issue mentioned above: how the component library is maintained (consider a scenario where new components are added to meet business needs).

There are two common ways to do this:

  • Put it directly in the project
  • The NPM package is extracted to form a separate third-party component library

If it is in the early stage of the project, I feel that the first approach is not impossible, convenient debugging. However, in the long run, the components precipitated under the marketing scenario will never be less. It is a wise choice to take third party NPM package. At the same time, we should cooperate with a management system similar to component management background to make unified management of components.

Going back to the components themselves, there must be strict development specifications. Each component is different in principle only in presentation, which must be followed by the established component development specifications. As for how to limit, this can be done through documentation (weak) or CLI (strong).

The template

In addition to the above problems, there is one thing I didn’t mention: templates. We know that marketing campaigns have a typical feature: similar pages. It would take a lot of time for operations/product students to generate a page from zero, and most of the activities fall under a certain category, so we can extract these similar activities as templates. Creating based on templates saves a lot of time and effort. Since this part of the content is still under development and migration, I won’t go into details for now.

At this point, I feel like I’ve answered some of the most complex parts of the visual editor implementation in the form of a question. In fact, whether it is dynamic component loading, component schema design, data structure design, component library maintenance, etc., each team can develop a set of specifications suitable for their own, there is no absolute right or wrong.

In fact, in the implementation process of this editor, there are a lot of low-level implementation details that cannot be ignored. Include:

  • Drag and drop
  • Component layer hierarchy
  • Zoom in/out
  • Undo/Redo
  • The adsorption
  • Bind event/animation

I won’t go into these details, but I recommend an article: Visual Drag and Drop Component Library. The technical points mentioned above are explained in detail in the article.

low code/no code/pro code

With that said, let’s go back to low code/no code/pro code at the beginning of this article. I’ll illustrate all three in conjunction with our visual editor.

First, let’s look at the general process of creating an activity with the editor:

no code

First of all, a brief explanation of what is no code: literally, no code, no code.

From the flowchart above, you can see that the operations/product students can build a fully functional activity page through the visual editor without writing a line of code. This corresponds to no code.

low code

Low code is defined as less code, less code.

In the flowchart above, it is more reflected in the front end of the student development component library. Need to write part of the code, the whole way through the drag-and-drop generation. The equivalent is low code.

pro code

The definition of pro code is pure code, that is, it relies on the development of handwritten code form without any visual tools. In the days before low code and no code, this was the most common way to develop.

In the flowchart above, this part is not shown. However, in the real business development, this scenario is often present. It is possible that a current marketing campaign has complex interactions and long links, which is difficult to customize through this visual editor. Business requirements can only be met by developers writing code manually.

Visual editors are designed to meet similar page development rules, and the primary responsibility is to mitigate repetitive business development

Looking forward to

At this point, a marketing system to explore the evolution of the process I basically comb finished.

But this is only the beginning. This article focuses more on the front-end side of the exploration, and is only the first step towards a visual editor, but it is a more front-end project, a lot of logic is not considered yet. Here’s what to do next:

  • Template market
  • The data center
  • Buried point
  • Component debugging/preview
  • The cache
  • Open API Capability
  • CDN
  • Across the
  • .

❤️ Love three

1. If you think this article is not bad, come to share, thumb up, in the Sanlian bar, let more people also see ~

2. Pay attention to the forest at the front of the public account, and regularly push good articles of fresh dry goods for you.

3. At special stage, wear a mask and do a good job of personal protection.