此項目是上古項目,代碼基本很難維護,如今發佈出來僅供參考思路,感興趣的能夠根據原理重構一版,實現一個更完備的可視化編輯javascript
友情提醒:不建議在團隊內投入大量精力作相似的事情(企圖一步到位改變開發現狀),與行業裏用 AI 切頁面相似,儘可能做爲玩具把玩一下便可。html
Github 地址:github.com/xinyu198736…java
xinyu198736.github.io/antd-visual…react
託管在 github,第一次加載會比較慢webpack
截圖:git
npm run build; npm run start; # 由於我不太懂 webpack ,不太會配置,這個項目修改代碼後實時生效還有問題。。求 pr 複製代碼
第一步,抽象整個可視化工做臺的數據表達,無非是放了一個什麼組件在什麼位置,這個組件的父組件是誰,這個組件的屬性是什麼github
以下圖:web
一個組件的基礎定義:npm
title 組件名 type 組件類型(組件真實類名) can_place 組件是否能夠包含子組件 children 組件的子組件,數組類型 is_native 組件是不是原生 html 元素 config 組件可用的配置信息 props 組件配置信息的值,包含樣式和屬性等 複製代碼
根據這些值,咱們就能夠渲染和編輯組件了,編輯組件後, 會有一個大的表示畫布當前狀態的數據結構存儲到 state 中, 另外,有一個方法能夠根據這個數據結構渲染出整個畫布, 因此每次有任何編輯動做以後,咱們會觸發 forceUpdate,從新繪製畫布 也就是說,添加組件,編輯屬性,和畫布的顯示是分離的,中間由一個大的數據結構鏈接(就是圖片裏這個)數組
根據上圖中的數據結構,反向遍歷,可輕易的生成 React 代碼
在 pages/coms/xxx 裏面定義一個組件的可用配置,而後便可在主界面中選擇組件後在右側"屬性編輯區"中編輯屬性。
來看看咱們能夠定義哪些屬性吧
以一個按鈕爲例
export default { "type": "Button", "title": "按鈕", "props": { type: 'primary', // 定義能夠配置的 props content: '按鈕一隻', // 定義能夠配置的 props style: { // 定義能夠配置的樣式 margin: "0px 10px 0px 0px" } }, config: { // 可用的配置項 type: { // type 這個配置的描述 text: "主題", // 配置的標題 enum: [ // 可用的枚舉,配置時會顯示成下拉框 'primary', 'default', 'dashed', 'danger' ] }, icon: { text: "圖標", }, content: { text: '文案', }, style: { // 可用的樣式配置 width: { text: "寬度", }, margin: { text: "外邊距", type: "4-value" // 一種定製類型,會渲染成 4 個輸入框 } } }, } 複製代碼
這是最基本的配置項,只能適用於最基本的組件,可是遇到像 table 或者 Breadcrumb 這種組件就不行了
以 Breadcrumb 爲例,他有一個數據源的屬性,數據源是一個數組+對象的混合表達,這種組件很多,應該如何定義呢
export default { "type":"Breadcrumb", "title":"麪包屑", props:{ routes:[ // 這裏是數據源的屬性,和默認值 { breadcrumbName:"一級目錄", path:"#", key:1 }, { breadcrumbName:"二級目錄", path:"#", key:2 } ] }, config:{ routes:{ // 如何表達這個屬性應該如何配置 text:"項目配置", enumobject:[{ // 一種新的類型,enumobject,對象枚舉 key:1, dataIndex:"breadcrumbName", // 枚舉的對象的第一個 key 是什麼 title:"顯示文本", // 枚舉的對象的第一個 key 的文本描述 type:'String', // 枚舉的對象的第一個 key 的類型 },{ key:2, dataIndex:"path", // 枚舉的對象的第二個 key 是什麼 title:"連接", // 枚舉的對象的第二個 key 的文本描述 type:'String', //枚舉的對象的第二個 key 的類型 }] } } } 複製代碼
最終的屬性編輯區:
便可邊界對象枚舉屬性
你們會發現,table 這種組件和上述的組件都不太同樣,首先看純數據表格
其實這裏還好,只是 table 有兩個屬性,一個表達列的數據,一個表達行的數據,咱們只須要兩個對象枚舉便可
{ config:{ columns:{ text:"列管理", enumobject:[ { title: '列文本', dataIndex: 'title', type:"String" }, { title: '列key', dataIndex: 'dataIndex', type:"String" } ] }, dataSource:{ text:"值管理", enumobject:{ type:'relative_props_object', target:'columns' } } } } 複製代碼
這裏實現了一個 關聯,能夠把 dataSource 的配置和 columns 關聯起來 (relative_props_object)
若是隻是數據,還好, 可是 table 裏能夠還能夠嵌套其餘組件,每行每列,想一想是否是頭疼。。以下圖
table 的每一個 column 其實能夠定義內部顯示的元素,咱們在默認值裏就給他塞一個空的 layout 進去, 這樣以後這裏就會變成一個能夠放置其餘子元素的坑,具體不展開了,這裏的邏輯比較複雜。
未完待續,或者直接看代碼。。