魯班H5核心原理解析(開源版本的拖拽生成H5平臺,功能相似易企秀的開源可視化搭建系統)javascript
相關地址
魯班H5是什麼?
魯班H5是基於Vue2.0開發的,經過拖拽的形式,生成頁面的工具,相似易企秀、百度 H5,是一款開源的可視化搭建系統css
核心原理解析
> 本文中提到的「H5」均指代「基於移動端傳播的可交互(不限於播放影音,頁面滑動,擦除,頁內動畫,表單收集等方式)的輕量網站」)。至關於微信上的PPT,主要用於品牌方傳播和推廣的載體 - 摘自一個Geek範的H5頁面製做工具html
要解決的問題
從實現原理來講,其實須要解決的就是如下幾個問題:vue
須要有哪些能夠編輯的元素?
文本、圖片、形狀、音頻、連接等,二期之後會逐步增長更多的可編輯元素。java
如何編輯元素?
經過點擊或者上傳的形式新增,經過拖拽來調整大小尺寸及位置,經過編輯面板來修改樣式。同時,不一樣的元素將擁有不一樣的編輯面板,如文字類型,能夠修改字體、顏色、大小、對齊方式等,而圖片類型,則能夠進行縮放、裁剪、圓角、陰影等調整。git
如何編輯和預覽動畫效果?
動畫效果將模仿其餘產品,合併至編輯面板,並經過點擊圖標的形式,更換不一樣的入場動畫,更換的同時,觸發本動畫的實際效果預覽。另外也能夠點擊獨立的預覽按鈕,能夠對已經編輯完畢的頁面進行預覽。github
如何實現與後臺的數據交互?
按頁和頁內元素組合成一個json對象,附帶音頻信息傳遞至後臺數據接口,讀取時一樣處理。json
如何將數據轉換成手機端網頁(所謂H5頁面)?
藉助vue的createElement方法,將json 逐一解析成對應的組件,渲染便可。<br>使用slider插件實現上下或者左右翻頁。segmentfault
如何實現兼容手機端網頁?
目前市面上,手動開發這類型網頁,通常有兩種兼容方式,即固定尺寸兼容及百分比兼容,我稱之爲主動兼容和被動兼容,區別主要是在與元素css的尺寸計算方式以及viewport的寫法,這類型文章網上已經有很多,這裏就再也不敷述。而在本項目當中,最終選擇的是二者相結合的方式來實現,緣由在以後的文章中會說起。數組
> 以上內容部分摘錄自來自:https://blog.csdn.net/tech_meizu/article/details/52288797
核心原理解析
將 JSON 轉換成 H5
回到 Vue 官方文檔中
相信閱讀過 Vue JSX 文檔 的同窗對下面的代碼應該不會陌生,能夠直接訪問 在線Demo <br>
// 如下代碼來自:https://cn.vuejs.org/v2/guide/render-function.html#createElement-參數 // @returns {VNode} createElement( // {String | Object | Function} // An HTML tag name, component options, or async // function resolving to one of these. Required. 'div', // {Object} // A data object corresponding to the attributes // you would use in a template. Optional. { // (see details in the next section below) }, // {String | Array} // Children VNodes, built using `createElement()`, // or using strings to get 'text VNodes'. Optional. [ 'Some text comes first.', createElement('h1', 'A headline'), createElement(MyComponent, { props: { someProp: 'foobar' } }) ] )
抽象抽象再抽象
咱們對上面的 demo 進行進一步的抽象:
- 移除註釋
- 把 createElement(tagName || componentOptions, {data}, children) 對應到上面的代碼中,把 children 部分單獨抽象成一個數組
- 整理以後的代碼以下:
// a component options demo: const MyComponent = { props:['someProp'], render(h) { return h('span', this.someProp) }, } new Vue({ el: '#app', // 這裏的 render(createElement) 咱們更常見的寫法是:render(h) // 關於這部分的解釋,能夠參見: https://segmentfault.com/q/1010000007130348?_ea=17466196 render(createElement) { const pageJSON = [ 'Some text comes first.', createElement('h1', 'A headline'), createElement(MyComponent /** component options */, { props: { someProp: 'foobar' } }) ] return h('div', {}, pageJSON) } }) // 再抽象一步 new Vue({ el: '#app', render(h) { const pageJSON = [ {component: 'span', text: 'Some text comes first.'}, {component: 'h1', text: 'A headline'}, {component: 'MyComponent', data: {props: {someProp: 'foobar'}} } ] return h('div', {}, pageJSON.map(ele => { return h(ele.component, ele.text ? ele.text : ele.data) })) } }) // 再抽象一步(哎,不對啊,做者,我咋感受你這一步啥都沒作啊😂,你說對了) const PageJSON = [ {component: 'span', text: 'Some text comes first.'}, {component: 'h1', text: 'A headline'}, {component: 'MyComponent', data: {props: {someProp: 'foobar'}} } ] new Vue({ el: '#app', render(h) { return h('div', {}, pageJSON.map(ele => { return h(ele.component, ele.text ? ele.text : ele.data) })) } }) // 再抽象一步 const WorkJSON = { title: '我是做品標題', description: '我是做品描述', created_time: '2019-09-01', updated_time: '2019-09-01', pages: [ elements: [ {component: 'span', text: 'Some text comes first.'}, {component: 'h1', text: 'A headline'}, {component: 'MyComponent', data: {props: {someProp: 'foobar'}} } ], ], } new Vue({ el: '#app', render(h) { return h('div', {}, WorkJSON.pages[0].elements.map(ele => { return h(ele.component, ele.text ? ele.text : ele.data) })) } })
- 相信到最後以這一步你們應該有些頭緒了吧(要沒有的話 😂😂😂,接着往下看吧)
- 其實魯班H5的一個做品實際上是一個就是一個大JSON(結構和上面的 WorkJSON 幾乎一致
- 這個大JSON 裏面包含了不少頁面(魯班源碼-Page),每一個頁面裏面包含了不少元素(魯班源碼-Element)
- 最終這個JSON 會傳給 render(h) 進行解析渲染
- 到這裏,也就能解答這一小節的問題了:
1. 魯班H5 的核心原理是什麼?? 2. 如何將數據轉換成手機端網頁(所謂H5頁面)? 3. JSON 轉換成 H5??
完結撒花 🎉🎉🎉🎉🎉🎉🎉🎉