基於React+Koa實現一個h5編輯器

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"前段時間筆者一直忙於"},{"type":"text","marks":[{"type":"strong"}],"text":"數據可視化"},{"type":"text","text":"方面的工作,比如如何實現"},{"type":"text","marks":[{"type":"strong"}],"text":"拖拽式"},{"type":"text","text":"生成可視化大屏,如何定製可視化圖表交互和數據導入方案等,這塊需求在B端企業中應用非常大,所以非常有探索價值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本篇文章並非和數據可視化相關,而是通過抽象技術底層,將其應用於"},{"type":"text","marks":[{"type":"strong"}],"text":"H5頁面可視化"},{"type":"text","text":"搭建上,通過技術的手段實現"},{"type":"text","marks":[{"type":"strong"}],"text":"拖拽式生成H5頁面"},{"type":"text","text":"。這塊也有非常多的應用場景,比如我們需要開發一個移動端網站,一個H5營銷頁面,H5活動頁面等,如果有這樣的傻瓜式拖拽的工具生成H5頁面,將會極大的提高我們的工作效率。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來筆者將對"},{"type":"text","marks":[{"type":"strong"}],"text":"h5頁面可視化編輯器-Dooring"},{"type":"text","text":"做詳細的項目分析和原理解讀,來帶大家深入瞭解h5可視化搭建頁面的原理和技術實現。H5編輯器預覽如下:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8b/8b60240cd9270815cf5be3432645e4eb.png","alt":"","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"github地址:"},{"type":"link","attrs":{"href":"https://github.com/MrXujiang/h5-Dooring","title":null},"content":[{"type":"text","text":"傳送門"}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"技術棧"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"React"},{"type":"text","text":" 前端主流框架(react,vue,angular)之一,更適合開發靈活度高且複雜的應用"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"dva"},{"type":"text","text":" 主流的react應用狀態管理工具,基於redux"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"less"},{"type":"text","text":" css預編譯語言,輕鬆編寫結構化分明的css"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"umi"},{"type":"text","text":" 基於react的前端集成解決方案"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"antd"},{"type":"text","text":" 地球人都知道的react組件庫"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"axios"},{"type":"text","text":" 強大的前端請求庫"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"react-dnd"},{"type":"text","text":" 基於react的拖拽組件解決方案,具有優秀的設計哲學"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"qrcode.react"},{"type":"text","text":" 基於react的二維碼生成插件"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"zarm"},{"type":"text","text":" 基於react的移動端ui庫,輕鬆實現美觀的H5應用"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"koa"},{"type":"text","text":" 基於nodejs的上一代開發框架,輕鬆實現基於nodejs的後端開發"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"@koa/router"},{"type":"text","text":" 基於koa2的服務端路由中間件"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"ramda"},{"type":"text","text":" 優秀的函數式js工具庫"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"需求分析"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在思考需求分析之前我們先來看看"},{"type":"text","marks":[{"type":"strong"}],"text":"Dooring"},{"type":"text","text":"的使用演示:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6d/6deec225d133ee0c23aefa96bc69654e.gif","alt":"","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由上面的gif圖我們可以分析出,可視化編輯器主要有以下幾部分組成:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可拖拽的組件庫 draggable components"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"盛放組件的畫布 canvas"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"組件編輯器 FormEditor"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"頭部工具欄 toolBar"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可拖拽組件我們可以用社區比較火的"},{"type":"text","marks":[{"type":"strong"}],"text":"react-dnd"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"react-draggable"},{"type":"text","text":"來實現,由於我們的畫布是可拖拽可放大縮小的,所以這裏需要對畫布賦能,具體實現可參考下文。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其次就是H5編輯器部分,這部分是核心功能,後面我們會詳細分析。還有就是預覽,生成預覽鏈接,保存"},{"type":"text","marks":[{"type":"strong"}],"text":"json"},{"type":"text","text":"文件, 保存模版這些功能本質上是對我們"},{"type":"text","marks":[{"type":"strong"}],"text":"json"},{"type":"text","text":"文件的操作,可是目前可視化搭建技術的常用手段之一。先來看看這些功能的演示:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8b/8b60240cd9270815cf5be3432645e4eb.png","alt":"","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"基礎準備"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們的"},{"type":"text","marks":[{"type":"strong"}],"text":"h5頁面可視化編輯器"},{"type":"text","text":"採用"},{"type":"text","marks":[{"type":"strong"}],"text":"umi"},{"type":"text","text":"來作爲腳手架工具."}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"umi"},{"type":"text","text":"是可擴展的企業級前端應用框架,以路由爲基礎的,同時支持配置式路由和約定式路由,保證路由的功能完備,並以此進行功能擴展。然後配以生命週期完善的插件體系,覆蓋從源碼到構建產物的每個生命週期,支持各種功能擴展和業務需求."}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣我們不會關注繁瑣的工程配置細節, 可以直接在項目中使用 "},{"type":"text","marks":[{"type":"strong"}],"text":"antd"},{"type":"text","text":" 和 "},{"type":"text","marks":[{"type":"strong"}],"text":"less"},{"type":"text","text":" 這些方案, 並且集成了目前比較流行的"},{"type":"text","marks":[{"type":"strong"}],"text":"css module"},{"type":"text","text":", 可以方便我們在項目裏對"},{"type":"text","marks":[{"type":"strong"}],"text":"css"},{"type":"text","text":"進行模塊化開發. umi創建項目的具體使用流程如下:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"// 創建並進入工程目錄\nmkdir dooring && cd dooring\n// 創建umi應用\nyarn create @umijs/umi-app\n// 安裝依賴\nyarn // 或者使用npm install\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"簡單的三步走策略就能輕鬆搭建我們的項目工程, 是不是省去了很多麻煩? (在使用這些方式之前我們首先確保自己本地的"},{"type":"text","marks":[{"type":"strong"}],"text":"node"},{"type":"text","text":" 版本是 10.13 或以上)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在項目搭建完成之後我們調整一下目錄結構, 具體如下:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"dooring \n├─ src \n│ ├─ assets \n│ │ └─ yay.jpg \n│ ├─ components \n│ ├─ layouts \n│ │ ├─ __tests__ \n│ │ │ └─ index.test.js \n│ │ ├─ index.css \n│ │ └─ index.js \n│ ├─ models \n│ │ └─ editor.js \n│ ├─ pages \n│ │ ├─ __tests__ \n│ │ │ └─ index.test.js \n│ │ ├─ editor \n│ │ │ ├─ components \n│ │ │ │ └─ FormEditor \n│ │ │ │ ├─ index.js \n│ │ │ │ └─ index.less \n│ │ │ ├─ container.js \n│ │ │ ├─ index.js \n│ │ │ └─ index.less \n│ │ ├─ index.css \n│ │ └─ index.js \n│ ├─ service \n│ │ └─ editor.js \n│ ├─ app.js \n│ └─ global.css \n├─ package.json \n└─ webpack.config.js \n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"page目錄下的editor使我們的主頁面, components存放我們的公共組件, models和service主要負責處理dva的狀態管理邏輯, 其他部分大家可以更具需求自由定義.此處僅供學習參考."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在項目創建完之後我們還需要安裝可視化方面必備的第三方組件, 筆者調研社區精選組件之後採用了一下方案:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"react-dnd"},{"type":"text","text":" react拖拽組件"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"react-color"},{"type":"text","text":" react顏色選擇組件,用於H5編輯器的編輯顏色部分"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"react-draggable"},{"type":"text","text":" 用於組件或者畫布的拖拽移動"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"react.qrcode"},{"type":"text","text":" 基於react的二維碼生成組件, 能以react組件的方式生成二維碼"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上組件在運行項目前大家可以自行安裝."}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"正文"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在最好項目開發準備之後,我們就來開始設計我們的h5頁面可視化編輯器-"},{"type":"text","marks":[{"type":"strong"}],"text":"Dooring"},{"type":"text","text":"."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"H5編輯器實現"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"H5可視化編輯器主要需要4個部分,在文章開頭也分析過, 這裏用圖來鞏固一下:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/10/102897a349673d59f93bdca818aa0a33.png","alt":"","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上是最基本也是最核心的功能展示模型,接下來我們會一一將其拆解並逐個實現."}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"實現原理"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們都知道, 目前比較流行的頁面可視化搭建方案可以有如下幾種:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在線編輯代碼實現"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在線編輯json實現"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"無代碼化拖拽實現(底層基於json配置文件)"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"筆者做了一下優缺點對比圖,如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"方案定製化程度缺點在線編輯代碼最高使用成本高,對非技術人員不友好,效率低在線編輯json較高需要熟悉json,有一定使用成本, 對非技術人員不友好,效率一般無代碼化拖拽實現高使用成本低, 操作基本無門檻,效率較高"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由以上分析來看, 爲了開發一個低門檻, 對任何人適用的可視化編輯器, 筆者將採用第三種方案來實現, 目前市面上已有的產品也有很多, 比如說易企秀, 兔展, 百度H5等等. "},{"type":"text","marks":[{"type":"strong"}],"text":"實現原理其實還是基於json, 我們通過可視化的手段將自己配置的 頁面轉化爲json數據,最後在基於json渲染器來動態生成H5站點"},{"type":"text","text":"."}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/16/16ec7292e9c4812d75f27cef78210497.png","alt":"","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"數據結構設計"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了提供組件的自定義能力,我們需要定義一套高可用的數據結構, 這樣才能實現因組件需求變更而帶來的維護性優勢."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在開始設計數據結構之前我們先來拆解一下模塊:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b5/b506c9d39764b053275b5f886134c0de.png","alt":"","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不同的組件都對應不同的\"編輯區域\".我們需要設計一套統一的標準的配置來約定它, 這樣對於表單編輯器的設計也非常有利, 具體拆解如下:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/87/872b5839a3db1096374b6ae2fe2a4e45.png","alt":"","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"經過以上分析之後, 筆者設計了類似下面的數據結構:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"\"Text\": {\n \"editData\": [\n {\n \"key\": \"text\",\n \"name\": \"文字\",\n \"type\": \"Text\"\n },\n {\n \"key\": \"color\",\n \"name\": \"標題顏色\",\n \"type\": \"Color\"\n },\n {\n \"key\": \"fontSize\",\n \"name\": \"字體大小\",\n \"type\": \"Number\"\n },\n {\n \"key\": \"align\",\n \"name\": \"對齊方式\",\n \"type\": \"Select\",\n \"range\": [\n {\n \"key\": \"left\",\n \"text\": \"左對齊\"\n },\n {\n \"key\": \"center\",\n \"text\": \"居中對齊\"\n },\n {\n \"key\": \"right\",\n \"text\": \"右對齊\"\n }\n ]\n },\n {\n \"key\": \"lineHeight\",\n \"name\": \"行高\",\n \"type\": \"Number\"\n }\n ],\n \"config\": {\n \"text\": \"我是文本\",\n \"color\": \"rgba(60,60,60,1)\",\n \"fontSize\": 18,\n \"align\": \"center\",\n \"lineHeight\": 2\n }\n}\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過這種標準化結構設計之後,我們可以很方便的實現我們所需要的編輯頁面的功能, 並且後期擴展非常方便, 只需要往editData添加配置即可. 至於動態表單編輯器的實現,方案有很多, 筆者之前也寫過相關的文章, 這裏就不詳細介紹了."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"基於react搭建一個通用的表單管理配置平臺(vue同)"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"組件庫設計"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"組件庫設計考慮的一個重要的問題就是體積和渲染問題, 一旦組件庫變的越來越多, 那意味着頁面加載會非常慢,所以我們需要實現異步加載組件和代碼分割的能力, umi提供了這樣的功能,我們可以基於它提供的api去實現自己的額按需組件."}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"import { dynamic } from 'umi';\n\nexport default dynamic({\n loader: async function() {\n // 這裏的註釋 webpackChunkName 可以指導 webpack 將該組件 HugeA 以這個名字單獨拆出去\n const { default: HugeA } = await import(/* webpackChunkName: \"external_A\" */ './HugeA');\n return HugeA;\n },\n});\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過以上的方式來定義包裹我們的每一個組件, 這樣就能實現按需加載了, 但是最好的建議是不需要每個組件都按需加載和拆包,對於"},{"type":"text","marks":[{"type":"strong"}],"text":"標題"},{"type":"text","text":", "},{"type":"text","marks":[{"type":"strong"}],"text":"通知欄"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"頁頭"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"頁腳"},{"type":"text","text":"這些組件, 我們完全可以把它放在一個組裏,這樣不但對不會影響加載速度, 還能減少一定的http請求."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"筆者這裏簡單舉一個組件實現的例子,方便大家理解:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"const Header = memo((props) => {\n const { \n bgColor,\n logo,\n logoText,\n fontSize,\n color\n } = props\n return
\n
\n {logoText}\n
\n
{ logoText }
\n
\n})\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面的Header組件的props屬性完全是由我們之前設計的json結構來定義的,在用戶編輯的過程中將收據收集並傳給Header組件。最後一步是將這些組件動態傳給"},{"type":"text","marks":[{"type":"strong"}],"text":"dynamic"},{"type":"text","text":"組件, 這塊在上文也介紹過了,大家可以根據自己的實現來做動態化渲染。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"實現預覽功能"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"預覽功能這塊比較簡單, 我們只需要將用戶生成的json數據丟進H5渲染器中即可, 這裏我們需要做一個渲染頁面單獨用來預覽組件. 先來看看幾個預覽效果:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/cc/cc2a3120fa3e9f91b8e4232ddba0b634.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/56/56dcc4129cf232980c2828be4ac04fbe.png","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"前面的渲染器原理已經介紹了, 這裏就不一一介紹了,感興趣的可以交流討論."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"實現在線下載功能"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在線下載這塊我們需要用到一個開源庫: "},{"type":"text","marks":[{"type":"strong"}],"text":"file-saver"},{"type":"text","text":", 專門解決前端下載文件困難的窘境. 具體使用舉例:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var FileSaver = require('file-saver');\nvar blob = new Blob([\"Hello, world!\"], {type: \"text/plain;charset=utf-8\"});\nFileSaver.saveAs(blob, \"hello world.txt\");\n複製代碼"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以上代碼可以實現將傳入的數據下載爲txt文件, 如果是Blob, 是不是還能在線下載圖片, html呢? 答案是肯定的, 所以我們的下載任務採用該方案來實現."}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"後端部分實現"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"後端部分由於涉及的知識點比較多, 不是本文考慮的重點, 所以這裏大致提幾個點, 大家可以用完全不同的技術來實現後臺服務, 比如說"},{"type":"text","marks":[{"type":"strong"}],"text":"PHP"},{"type":"text","text":", "},{"type":"text","marks":[{"type":"strong"}],"text":"Java"},{"type":"text","text":", "},{"type":"text","marks":[{"type":"strong"}],"text":"Python"},{"type":"text","text":"或者"},{"type":"text","marks":[{"type":"strong"}],"text":"Egg"},{"type":"text","text":". 筆者這裏採用的是"},{"type":"text","marks":[{"type":"strong"}],"text":"koa"},{"type":"text","text":". 主要實現功能如下:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"保存模板"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"真機原理的數據源存儲"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用戶相關功能"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"H5圖牀和靜態文件託管"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"具體代碼可以參考筆者的另一篇全棧開發文章"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"基於nodeJS從0到1實現一個CMS全棧項目"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"模式基本一致."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"github地址:"},{"type":"link","attrs":{"href":"https://github.com/MrXujiang/h5-Dooring","title":null},"content":[{"type":"text","text":"Dooring傳送門"}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"後期規劃"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"後期"},{"type":"text","marks":[{"type":"strong"}],"text":"Dooring"},{"type":"text","text":"項目規劃如下:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"豐富組件庫組件,添加可視化組件"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"添加配置交互功能"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"組件細分和代碼優化"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"添加PC端搭建平臺"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"添加表單設計平臺"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"添加typescript支持和單元測試"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"最新迭代功能"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"優化H5編輯器界面"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"添加可視化組件——進度條"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"修復win下預覽樣式問題,添加移動端訪問出現提示頁"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"最後"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果想學習更多"},{"type":"text","marks":[{"type":"strong"}],"text":"H5遊戲"},{"type":"text","text":", "},{"type":"text","marks":[{"type":"strong"}],"text":"webpack"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"node"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"gulp"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"css3"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"javascript"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"nodeJS"},{"type":"text","text":","},{"type":"text","marks":[{"type":"strong"}],"text":"canvas數據可視化"},{"type":"text","text":"等前端知識和實戰,歡迎在《趣談前端》一起學習討論,共同探索前端的邊界。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章