一個較爲完備的 antd 可視化編輯器實現

此項目是上古項目,代碼基本很難維護,如今發佈出來僅供參考思路,感興趣的能夠根據原理重構一版,實現一個更完備的可視化編輯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
複製代碼

特性

  • 可視化編輯,同時實時生成結果代碼,還能夠單獨預覽
  • 豐富的數據編輯能力,能夠編輯組件的二維屬性
  • 組件可嵌套
  • 自適應佈局
  • 除了 antd 的組件,還有一些原生 html 元素可以使用

原理解析

1.如何實現實時編輯

第一步,抽象整個可視化工做臺的數據表達,無非是放了一個什麼組件在什麼位置,這個組件的父組件是誰,這個組件的屬性是什麼github

以下圖:web

一個組件的基礎定義:npm

title 組件名
type  組件類型(組件真實類名)
can_place 組件是否能夠包含子組件
children 組件的子組件,數組類型
is_native 組件是不是原生 html 元素
config  組件可用的配置信息
props 組件配置信息的值,包含樣式和屬性等
複製代碼

根據這些值,咱們就能夠渲染和編輯組件了,編輯組件後, 會有一個大的表示畫布當前狀態的數據結構存儲到 state 中, 另外,有一個方法能夠根據這個數據結構渲染出整個畫布, 因此每次有任何編輯動做以後,咱們會觸發 forceUpdate,從新繪製畫布 也就是說,添加組件,編輯屬性,和畫布的顯示是分離的,中間由一個大的數據結構鏈接(就是圖片裏這個)數組

2.如何反向生成 react 代碼

根據上圖中的數據結構,反向遍歷,可輕易的生成 React 代碼

3.如何定義組件可用的配置

在 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 這種組件就不行了

4.高級配置(二維數據)

以 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 的類型
          }]
    }
  }
}
複製代碼

最終的屬性編輯區:

便可邊界對象枚舉屬性

5.更復雜的組件

你們會發現,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)

6.更更復雜的表格

若是隻是數據,還好, 可是 table 裏能夠還能夠嵌套其餘組件,每行每列,想一想是否是頭疼。。以下圖

table 的每一個 column 其實能夠定義內部顯示的元素,咱們在默認值裏就給他塞一個空的 layout 進去, 這樣以後這裏就會變成一個能夠放置其餘子元素的坑,具體不展開了,這裏的邏輯比較複雜。

未完待續,或者直接看代碼。。

相關文章
相關標籤/搜索