前言
本項(xiàng)目旨在開發(fā)一個供運(yùn)營、產(chǎn)品快速搭建商城的可視化平臺,利用可視化的拖拽與屬性配置完成商城構(gòu)建和日常運(yùn)營,而開發(fā)只進(jìn)行平臺的維護(hù)、業(yè)務(wù)組件的新增和迭代。避免高頻的業(yè)務(wù)需求,提升我們的開發(fā)效率。
本項(xiàng)目提供的是可視化搭建平臺模板,大家可根據(jù)公司實(shí)際需求進(jìn)行修改,最終形成滿足自己實(shí)際需求的可視化搭建平臺。
接下來我將帶大家深入的了解Mall-Cook可視化平臺的原理與技術(shù)實(shí)現(xiàn)。Mall-Cook可視化平臺預(yù)覽如下:

)
github地址:傳送門
預(yù)覽地址:傳送門
開發(fā)前規(guī)劃
明確目標(biāo)人群
在進(jìn)行具體開發(fā)前,首先我們需要明確我們開發(fā)的平臺是給誰用的?是面向運(yùn)營還是面向研發(fā)?研發(fā)人員適合low-code(低代碼平臺),而非研發(fā)人員適合no-code(無代碼平臺)。

我覺得兩者最大的區(qū)別是組件通訊,也就是大家經(jīng)常會問的組件怎么交互?
我舉個栗子

low-code我推薦大家了解下云鳳蝶我認(rèn)為現(xiàn)在最期待的中后臺搭建平臺,平臺理論可接入任意組件庫或NPM組件,強(qiáng)大的解析器解析組件為平臺所用。通過狀態(tài)外置進(jìn)行組件通訊,簡單理解每個頁面有個自己vuex,可以自定義狀態(tài)(變量)、方法,根據(jù)需要把狀態(tài)、方法綁定組件,實(shí)現(xiàn)組件的交互,云鳳蝶在知乎有幾篇介紹的文章。云鳳蝶yyds!
no-code首推政采云的魯班,有贊與微盟雖然是獨(dú)角獸級別的模板,但是它們太太太大了,我也找不到核心架構(gòu)文章,無法深度了解。而魯班手把手詳細(xì)給我講解了可視化搭建的內(nèi)核,schema的作用與重要性,雖然體量與復(fù)雜度無法與有贊與微盟相比,但它是教會我的那個人。
選擇畫布布局方案

對于布局方案,我們只取決于兩個點(diǎn)中的一個,自由或便捷,其他的大多是噱頭。
自由布局適合與大屏與中后臺系統(tǒng),因?yàn)槠漤撁孀杂啥雀?,物料間可相互覆蓋。
那為什么流式布局適合H5與小程序呢?
我舉個栗子,比如H5頁面中,你的商品列表是根據(jù)網(wǎng)絡(luò)接口實(shí)時查詢,當(dāng)商品數(shù)量發(fā)生變化導(dǎo)致商品列表組件高度變化時,我們通過流式布局保證布局不受影響。
其他布局:舉個反栗凡科技提供的是類自由布局,這是除我上述兩種布局外,其他布局想實(shí)現(xiàn)的功能基本齊了,支持父子組件間的嵌套、自由拖拽、顆?;A(chǔ)物料(text、button)??粗δ芏箭R了,但我實(shí)際使用發(fā)現(xiàn)操作復(fù)雜不實(shí)用,且只能進(jìn)行部分靜態(tài)樣式的自定義。同樣是一個商品列表,我想通過拖拽自定義單項(xiàng)樣式,或者我想給沒他banner圖片自定義添加文字,發(fā)現(xiàn)這種動態(tài)組件同樣只能靠配置項(xiàng)設(shè)置。結(jié)論發(fā)現(xiàn)實(shí)用性并不高,反而搭建頁面比單純流式布局復(fù)雜數(shù)倍。
布局我只推薦流式布局和自由布局,其他的附加功能大多是噱頭大于實(shí)際,具體附加功能根據(jù)實(shí)際場景決定是否添加。
比如組件嵌套功能,我在頁面配置中未提供此功能,這不是不能實(shí)現(xiàn),而是組件嵌套一般用類似在TAB欄的容器中,可在每個TAB中嵌套不同的組件,我覺得為了這個實(shí)現(xiàn),而提供頁面組件的無限嵌套的復(fù)雜邏輯不值得。而在Schema協(xié)議生成器中提供了Object、Array對象類型的組件嵌套,是因?yàn)閿?shù)據(jù)結(jié)構(gòu)是可以任意嵌套的,比如props接收一個對象數(shù)組類型的數(shù)據(jù)。是否需要某個功能根據(jù)實(shí)際實(shí)用場景而定,而不是我全都要,越多就覺得越厲害。對用戶而言,操作越簡單越友好,可以看有贊、微盟方案。對于流式布局鉗制自由度的劣勢,用大量業(yè)務(wù)組件、頁面模板填充,目的就是讓用戶操作簡單。
單純流式布局看起或許很low,但是操作越是簡單,用戶才越是方便。我想做的是能實(shí)用的工具,而不是看起來有點(diǎn)炫的玩具。
確定可視化平臺開發(fā)的核心
可視化平臺開發(fā)的核心是什么?
是一個可拖拽的組件列表,一個展示組件畫布,一個組件屬性控制面板組成的控制中心?是一套看起功能眼花繚亂的布局方式?
不,是規(guī)范,一套規(guī)范。
每個成熟的可視化平臺,都會經(jīng)歷長期的迭代升級,無數(shù)實(shí)用的業(yè)務(wù)組件會在其后大量的新增與迭代,一套標(biāo)準(zhǔn)的規(guī)范才能使平臺健康成長直至成熟穩(wěn)定。
那怎么要定義規(guī)范?定義規(guī)范有什么用?
我們說個最簡單的,定義組件的規(guī)范。
一個標(biāo)題組件接入平臺,我不會關(guān)心你的內(nèi)部實(shí)現(xiàn),我只關(guān)心你的props入?yún)?,我怎么通過屬性配置面板去控制你。

- 原始方式 寫一個包含title字段輸入框的表單的配置面板
- 進(jìn)階方式 為每個組件寫一個JSON去描述組件的關(guān)鍵信息,給它配張身份卡供我們平臺識別。
// 組件描述JSON
{
"label": "標(biāo)題組件", // 組件名
"icon": "icon-title", // 組件圖標(biāo)
"fields": { // 組件屬性
"title": { // 屬性名
"label": "標(biāo)題", // 屬性label
"type": "string", // 屬性類型
"value": "LEADING SERIES" // 屬性初始值
}
}
}
一旦進(jìn)入平臺我們就通過解析JSON身份卡,獲取組件信息。然后我們開發(fā)一個屬性配置器,傳入組件信息中的屬性數(shù)據(jù),通過屬性配置器生成屬性控制面板

進(jìn)階方式解耦、工業(yè)化,這樣才能在后面使大量組件接入平臺。然而有一個風(fēng)險點(diǎn)JSON是無規(guī)則的,組件描述JSON應(yīng)該按平臺定的規(guī)則來寫平臺才能識別,所以我們需要用規(guī)則來標(biāo)準(zhǔn)化JSON。
解決辦法就是通過JSON Schema協(xié)議來約束JSON,讓它根據(jù)我們定的標(biāo)準(zhǔn)來編寫。(后文有平臺Schema協(xié)議具體講解)
So,我們定義的Schema協(xié)議,是我們平臺規(guī)范的工具,也就是我們可視化開發(fā)平臺的核心。
平臺介紹
Mall-Cook平臺的目的是可視化構(gòu)建移動商城,商城構(gòu)建流程模仿有贊、微盟,平臺提供:
- 可視化推拽面板,流式布局
- 多頁面搭建
- 實(shí)時預(yù)覽
- H5頁面適配
- 自定義底部tab菜單
- 商品管理 (現(xiàn)為模擬商品,可修改接口管理真實(shí)商品)
- 商品分類管理,自定義商品分類頁
- 模板商城
- Schema生成器,可視化生成屬性控制面板
平臺速覽







項(xiàng)目結(jié)構(gòu)
├─ h5 // h5項(xiàng)目
│ ├─ api
│ ├─ assets
│ ├─ components
│ ├─ pages
│ ├─ router
│ ├─ store
│ ├─ utils
│ ├─ App.vue
│ └─ main.js
├─ src // admin項(xiàng)目
│ ├─ api
│ ├─ assets
│ ├─ components
│ ├─ config // 初始配置文件
│ ├─ custom-components // 物料庫
│ ├─ custom-schema-template // 屬性組件庫
│ ├─ custom-schema-template-set // 屬性面板生成器
│ ├─ mixin
│ ├─ pages
│ ├─ router
│ ├─ scss
│ ├─ store
│ ├─ utils
│ ├─ App.vue
│ └─ main.js
├─ package.json
├─ ftpUp.js // ftp上傳文件
└─ webpack.config.js
項(xiàng)目分為admin與h5兩個項(xiàng)目包,package.json支持分別/共同打包、一鍵部署
{
"name": "mall-cook",
"version": "0.1.0",
"scripts": {
"dev": "cross-env GZIP=false TYPE=admin vue-cli-service serve", //admin 啟動
"dev:h5": "cross-env GZIP=false TYPE=h5 vue-cli-service serve", // h5 啟動
"build:admin": "cross-env GZIP=true TYPE=admin vue-cli-service build --no-clean --mode development --report", // admin打包
"build:h5": "cross-env GZIP=true TYPE=h5 vue-cli-service build --no-clean --mode development --report", //h5 打包
"build:dev": "npm run build:h5 && npm run build:admin --mode development", // admin&h5共同打包
"deploy": "npm run build:dev && node ftpUp.js" // ftp部署 - 請?jiān)趂tpUp.js配置服務(wù)器信息
},
}
JSON Schema
基礎(chǔ)類型
又到了舉栗子的環(huán)節(jié)

這是一個基礎(chǔ)的屬性Form表單,包括輸入框、單選器、計(jì)數(shù)器,它們由各種元素組成。接下來我們用JSON來代表元素來組裝它們:



復(fù)合類型
我們除了基礎(chǔ)類型外,組件經(jīng)常也需要傳入對象、數(shù)組、對象數(shù)組等復(fù)合類型。我們應(yīng)該支持任何的復(fù)合類型。我們來看導(dǎo)航欄數(shù)據(jù)列表:

業(yè)務(wù)場景實(shí)例
從上面我們知道了怎么用JSON表示基礎(chǔ)類型和復(fù)合類型數(shù)據(jù),而一個組件props能接收任意數(shù)量任意類型的數(shù)據(jù)。接下來我們用導(dǎo)航欄組件來實(shí)際分析:

導(dǎo)航欄組件接收styles(對象)、attrs(對象)、tabList(對象數(shù)組)
props: {
styles: {
type: Object,
default: () => {}
},
attrs: {
type: Object,
default: () => {}
},
tabList: {
type: Array,
default: () => []
}
},
下面我們來一一細(xì)看:
[圖片上傳失敗...(image-a4b4c-1639209288830)]
[圖片上傳失敗...(image-d5e26b-1639209288830)]
[圖片上傳失敗...(image-6ac297-1639209288830)]
然后我們把各個接收數(shù)據(jù)合并在一起,再加上組件的基礎(chǔ)信息,就構(gòu)成了一個描述組件的JSON。

我們按照平臺JSON Schema協(xié)議寫的標(biāo)準(zhǔn)JSON可以讓平臺識別組件信息,再調(diào)用屬性解析器生成屬性控制面板來控制組件。
Schema 生成器
Json Schema 應(yīng)該要滿足兩點(diǎn):
- 定義JSON規(guī)則,約束JSON
- 檢驗(yàn)機(jī)制,可檢測當(dāng)前JSON是否滿足Json Schema規(guī)則
我們雖然定義了Json Schema,不過我們還沒有相對應(yīng)的檢驗(yàn)機(jī)制。我怎么知道我寫的JSON是否正確?這時我們應(yīng)該繼續(xù)開發(fā)個校驗(yàn)器,校驗(yàn)JSON。不過我選擇了一種更高效的方法,開發(fā)Schema 生成器,用工具來規(guī)則代碼,同時避免繁雜json的編寫
Schema 生成器功能:
- 所見即所得,可視化拖拽實(shí)際的屬性面板
- 支持對象組件(object、array)嵌套,構(gòu)成復(fù)合類型
- 自動生成全部JSON,無需用戶修改,直接引用
- 支持JSON引入功能,可把生成JSON引入,以供重復(fù)修改



結(jié)尾
Mall-Cook只是一個以構(gòu)建H5商城場景的項(xiàng)目模板,大家可以根據(jù)實(shí)際場景(比如酒5、外賣等)克隆項(xiàng)目修改邏輯。此項(xiàng)目的核心是實(shí)現(xiàn)從Schema生成到構(gòu)建一套完整可視化項(xiàng)目的標(biāo)準(zhǔn),拋磚引玉的讓大家了解Schema對可視化平臺的重要性。
未來平臺計(jì)劃
- 平臺迭代
后續(xù)會陸續(xù)加入更多的通用物料組件和商城的邏輯的完善
- 支持小程序
后面計(jì)劃把H5項(xiàng)目由uni-app替換,物料也移入uni-app中。利用uni-app一碼開發(fā)多端部署特點(diǎn),實(shí)現(xiàn)支持H5、小程序等多端。
- npm組件注冊
未來會試試實(shí)現(xiàn)npm組件在平臺的注冊與加載,最麻煩的應(yīng)該是npm組件的版本管理,這個很有挑戰(zhàn)性。(導(dǎo)入的自定義組件需提供components.json的組件描述json來識別組件)
未來可視化計(jì)劃
未來的話,我的計(jì)劃:
MALL-COOK 迭代
- 開發(fā)提供小程序版(uni-app)
- 開發(fā)小程序配置商城,Mall-Cook配置json傳入項(xiàng)目生成小程序
- 開發(fā)物料庫(uni-app版),可在現(xiàn)有小程序中引入物料庫,傳入Mall-Cook配置Json,自定義構(gòu)建單頁面
- 迭代提供大量業(yè)務(wù)組件
開發(fā)中后臺可視化代碼生成器
我原本計(jì)劃開發(fā)一個低配版云鳳蝶(可視化低代碼平臺)??墒亲屑?xì)考慮,這種項(xiàng)目除非業(yè)務(wù)固定或者像云鳳蝶開發(fā)完整度足夠高,滿足大量自定義需求,否則實(shí)用性較低。
所以計(jì)劃開發(fā)代碼生成器,生成器80%-90%基礎(chǔ)、重復(fù)功能,剩下自定義功能代碼開發(fā),提高中后臺開發(fā)效率。功能計(jì)劃如下:
平臺與element組件庫綁定
-
提供生成器配置功能包(只是基礎(chǔ)封裝,達(dá)到減少生成代碼作用,切記避免深度封裝,導(dǎo)致使用學(xué)習(xí)成本高,反而本末倒置)
- 單頁面mixin,提供公共數(shù)據(jù)方法定義,減少生成代碼
- 提供Pagination(分頁)、dialog、table、select、DatePicker等組件封裝,配套使用(是在element基礎(chǔ)上封裝,更方便使用,并減少生成代碼)
- 插拔式校驗(yàn)庫,配套使用(同樣提供方便,減少生成代碼)
開發(fā)類似yapi(低配版),api管理功能,并根據(jù)分頁接口數(shù)據(jù)模型,解析生成標(biāo)準(zhǔn)Json Schema
根據(jù)Json Schema生成CURD可視化表單(省去一般form generator,單個拖拽然后配置key的人工流程)
根據(jù)實(shí)際情況修改CURD表單每個單項(xiàng)
調(diào)整完成,生成vue代碼
開發(fā)目的
開發(fā)MALL-COOK包括后面的中后臺可視化代碼生成器,是想通過構(gòu)建小成本平臺提高基礎(chǔ)開發(fā)的效率。(項(xiàng)目自己一人開發(fā),精力有限,想通過較小開發(fā)成本進(jìn)行基建,可看早早聊堂主基建分享)
MALL-COOK開源的同時我也會在自己公司推出去,然后根據(jù)實(shí)際需求修改一下,即可上架給公司使用。同理大家也可根據(jù)自己的實(shí)際需求fork項(xiàng)目修改,然后使用。MALL-COOK的核心是從schema生成到項(xiàng)目生成的一套流程。至于具體業(yè)務(wù)大家可以自己DIY。
至于開發(fā)的原因?
基建不比天天寫CURD、寫H5有意思?