background

At present, the main business of many companies is c-terminal. With huge users and traffic, b-terminal business is indispensable, including CRM, CMS, operation configuration management platform, data visualization platform and various approval platforms. These systems have several characteristics in common: high demand, fast change, query page, list page, submit page. These pages are similar, with low UI requirements and simple functionality. So can we develop a set of configuration platform to liberate productivity? The answer is yes. We only need to configure Json to generate a page, how to do this? Let’s take our time……

Technology selection

Nodejs + Vue/React + Json schema

Frame structures,

Analysis: the page needs only one container, which can be interpreted as a Div. When loading the page, asynchronously go to the distributed configuration center (Redis or other) to get the page configuration, which is simply a Json string. After the configuration data is taken out, we start parsing Json, including the correctness, validity, and so on. Finally, Render the page through the Render method of the Vue component, seeing here, many people will have the following doubts:

  1. How to define the Json format?
  2. How does Json correspond to components?
  3. How is the component rendered?
  4. How do components communicate with each other?
  5. Support complex logical interactions?

Framework innovation and optimization

  • Support for infinite level component nesting rendering

  • Simplifies communication between components

  • The real-time preview page is configured

Question answer

1. How to define the Json format?

There is no uniform standard for this, but it is all based on personal preference. Let me show you my definition:

{
 "uniqueId": "mt-form"."attrs": {
 "style": {
 "paddingBottom": "15px"."paddingLeft": "5px"}}}Copy the code

2. How does Json correspond to components? Let’s start by looking at the code for a custom component form.vue:

<template>
 <el-form :label-width="labelWidth" :inline="true" class="mt-form-inline">
    <slot></slot>
 </el-form>
</template>
<script>
export default {
 props: ['labelWidth']
}
</script>
<style>
</style>Copy the code

A new component library module, ComponentSlib.js, is used to expose custom components:

/** * Import all common component libraries */ import Form from'./Form.vue'Module.exports = {/** * name must be unique */'mt-form': Form
} Copy the code

3. How are components rendered

Once we’ve written the component and exposed it, how do we render it? Define a global component with Vue.com Ponent:

import Vue from 'vue'
import ComponentsLib from './ComponentsLib'// Exposed component library /** * Inject global page container components * all components must be wrapped in a container component */ Vue.component('page-container', {
 render: function (createElement) {
 return this.deepComponents(this.pageConfig, createElement)
  },
 methods: {
 deepComponents (pageConfig, createElement) {
 if (pageConfig) {
 returncreateElement(ComponentsLib[pageConfig.uniqueId], { ... pageConfig.attrs }, this.deepChildren(pageConfig.children, createElement)) } }, @param {*} createElement */ deepChildren (pageConfig, createElement) {if(! pageConfig) {return createElement('span')}if (pageConfig) {
 let children = []
 for (let i = 0; i < pageConfig.length; i++) {
 let item = pageConfig[i]
 if(item) { children.push(createElement(ComponentsLib[item.uniqueId], { ... item.attrs }, this.deepChildren(item.children, createElement))) } }return children
      }
    }
  },
 props: {
 pageConfig: {
 type: Object,
 required: true}}})Copy the code

The main point can be seen that my components are exposed through the component library, and each component has a uniqueId, and the uniqueId is the uniqueId of my component when I configure it in Json. In this way, I can recursively Render my components through Vue.component’s Render method. This enables infinite level nesting of components.

Results the preview