此項目是上古項目,代碼基本很難維護,如今發佈出來僅供參考思路,感興趣的能夠根據原理重構一版,實現一個更完備的可視化編輯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 進去, 這樣以後這裏就會變成一個能夠放置其餘子元素的坑,具體不展開了,這裏的邏輯比較複雜。
未完待續,或者直接看代碼。。