背景
現在很多公司主要業務是c端,擁有巨大使用者和流量的同時,b端業務不可或缺,CRM,CMS,運營配置化管理平臺,資料視覺化平臺,各種審批平臺。這些系統都有幾個共同的特點:需求多,變化快,查詢頁,列表頁,提交頁面。而這些頁面都是相似的,UI要求低,功能簡單。所以我們能不能開發一套配置化平臺解放生產力呢?答案是肯定的。我們只需要配置一下Json就能生成一個頁面,這個如何實現呢?我們慢慢道來......
技術選型
Nodejs + Vue/React + Json schema
框架搭建
分析:頁面只需一個容器,可以理解為一個Div,在載入頁面的時候,非同步去分散式配置中心(Redis或其他)獲取頁面配置,頁面配置單純的就是個Json字串。配置資料取出來之後,我們開始解析Json,包括Json的正確性,合法性等。最後再通過Vue元件的Render方法渲染頁面,看到這裡,很多人會有如下的疑惑:
- Json格式如何定義?
- Json如何和元件對應起來?
- 元件是怎麼渲染出來的?
- 元件間如何通訊?
- 支援複雜的邏輯互動嗎?
框架創新及優化
- 支援無限級元件巢狀渲染
- 簡化元件間通訊
- 頁面配置實時預覽
疑問解答
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方法,可以遞迴遍歷渲染出我的元件,這樣就能實現元件的無限級巢狀。