如何搭建一個功能複雜的前端配置化框架(一)

背景

現在很多公司主要業務是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方法,可以遞歸遍歷渲染出我的組件,這樣就能實現組件的無限級嵌套。

效果預覽



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章