• 如何搭建一个功能复杂的前端配置化框架(一)


    背景

    现在很多公司主要业务是c端,拥有巨大用户和流量的同时,b端业务不可或缺,CRM,CMS,运营配置化管理平台,数据可视化平台,各种审批平台。这些系统都有几个共同的特点:需求多,变化快,查询页,列表页,提交页面。而这些页面都是相似的,UI要求低,功能简单。所以我们能不能开发一套配置化平台解放生产力呢?答案是肯定的。我们只需要配置一下Json就能生成一个页面,这个如何实现呢?我们慢慢道来......

    技术选型

    Nodejs + Vue/React + Json schema

    框架搭建

    分析:页面只需一个容器,可以理解为一个Div,在加载页面的时候,异步去分布式配置中心(分布式Redis或其他)获取页面配置,页面配置单纯的就是个Json字符串。配置数据取出来之后,我们开始解析Json,包括Json的正确性,合法性等。最后再通过Vue组件的Render方法渲染页面,看到这里,很多人会有如下的疑惑:

    1. Json格式如何定义?
    2. Json如何和组件对应起来?
    3. 组件是怎么渲染出来的?
    4. 组件间如何通信?
    5. 支持复杂的逻辑交互吗?

    框架创新及优化

    • 支持无限级组件嵌套渲染

    • 简化组件间通信

    • 页面配置实时预览

    疑问解答

    1. Json格式如何定义?

    这个没有统一的标准,完全按照个人喜好,给大家展示一下我的定义:

    {
     "uniqueId": "mt-form",
     "attrs": {
     "style": {
     "paddingBottom": "15px",
     "paddingLeft": "5px"
        }
      }
    }

    2. Json如何和组件对应起来? 我们先看一个自定义组件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>

    新建组件库模块ComponentsLib.js,我们把自定义组件通过这个模块暴露出去:

    /**
     * 引入所有公共组件库
     */
    import Form from './Form.vue'
    
    module.exports = {
     /**
       * 对外暴露组件,名称id必须唯一
       */
     'mt-form': Form
    } 

    3. 组件是怎么渲染出来的

    写了组件和暴露出组件之后,我们怎么渲染出来呢?通过Vue.component定义一个全局组件:

    import Vue from 'vue'
    import ComponentsLib from './ComponentsLib' // 暴露出来的组件库
    
    /**
     * 注入全局的页面容器组件
     * 所有组件必须包裹在一个容器组件中
     */
    Vue.component('page-container', {
     render: function (createElement) {
     return this.deepComponents(this.pageConfig, createElement)
      },
     methods: {
     deepComponents (pageConfig, createElement) {
     if (pageConfig) {
     return createElement(ComponentsLib[pageConfig.uniqueId], {
     ...pageConfig.attrs
            }, this.deepChildren(pageConfig.children, createElement))
          }
        },
     /**
         * 递归遍历所有子组件
         * @param {} pageConfig
         * @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
        }
      }
    })

    可以看出主要的一点,我的组件通过组件库暴露出来,并且每个组件都有一个唯一的ID,而我在Json中配置的时候uniqueId就是对应我组件的唯一ID,这样通过Vue.component的Render方法,可以递归遍历渲染出我的组件,这样就能实现组件的无限级嵌套。

    效果预览

  • 相关阅读:
    Iterable,Iterator和forEach
    集合的线程安全性
    Servlet生命周期
    JavaWeb应用的生命周期
    将博客搬至CSDN
    (五)新类库的构件
    Python input和print函数
    python----调试
    Excel决定吃什么
    MATLAB—地图
  • 原文地址:https://www.cnblogs.com/wukong-holmes/p/9287763.html
Copyright © 2020-2023  润新知