H5 可視化構建工具原理解析(一)

前言

總共進 8 萬行代碼實現H5可視化構建工具,自去年十月開始陸續作了大半年,現已投入到業務中使用,雖然算是我的項目,但組件和部署模塊涉及大量公司業務代碼,就不開源了,主要講講實現思路,算是該項目的回顧總結,將核心難點、重點作拆分解析,拆分紅系列不按期更新前端

成品圖

動圖太大,能夠點擊連接查看後端

技術棧

  • 前端 Vue-CLI3 全家桶、Electron、Graphql、Typescript、Stylus、Vuetify
  • 後端 Koa二、Graphql、Nuxt、MongoDB

爲何須要 H5 可視化構建工具

互聯網行業運營需求頻繁,並且需求週期短,每每只有一、2天開發時間,放在項目裏既拖慢總體編譯效率,同時又沒有任何意義,基本上都是當月做廢,同時對開發者自己沒有任何提高,重複勞動,咱們要作的就是經過工程的方式解放生產力,由運營同窗本身完成活動頁上線,而再也不須要開發資源微信

肯定產品原型

  • 提供可視化編輯的控制檯生成Vue SFC源碼
  • 能夠對已生成的頁面進行管理(編輯,上下線)
  • 控制檯提供自上而下的單列布局適配移動端H5,簡化操做邏輯
  • 添加的組件可編輯屬性、樣式、事件回調
  • 易於擴展的組件註冊機制

這是我早期畫的原型圖,原諒我拙劣的畫圖能力,看看就好編輯器

接下來,咱們對第一個會遇到的難點進行解析工具

如何儘量模擬移動端真實環境

方案一:經過子組件實現模擬佈局

  • 優勢:實現簡單,而且做爲子組件,狀態和行爲徹底受父組件控制
  • 缺點:因爲處於同一個window上下文,子組件的內容會被全局樣式污染,難以保證與實機一致,同時 UA和rem等相對尺寸會失效

方案二: 經過iframe建立獨立的window上下文來模擬post

  • 優勢:iframe包含完整的HTML代碼,擁有獨立的上下文,能夠儘量的模擬移動端環境
  • 缺點:數據不共享,只能經過PostMessage機制進行通訊

對於方案一,沒有獨立的window上下文,缺陷是不可逆的,而方案二除了通訊困難,其餘近乎完美,數據不共享的問題咱們能夠經過實現StateSync機制來實現,咱們這裏選擇方案二,那如何實現StateSync呢?ui

這裏只須要三個步驟spa

  1. 首先咱們把頁面編輯所須要的全部數據都提高到Vuex作全局存儲
  2. 監聽store中全部的數據變化

實現監聽store的僞代碼:線程

const store = new Vuex.Store({
    state:{
        // 頁面數據
        // ...
    },
    mutations:{
        //...
    },
});

// !因爲mutation是Vuex中最小的提交粒度,因此只須要監聽mutation就能夠監聽全部的數據變更
store.subscribe((mutation, state) => {

    // 數據發送
    // do someting ...
});
複製代碼

重點來了

  1. 當觸發mutation時將整個Vuex Module State 經過PostMessage發送給對方(主窗口/iframe)

數據流走向圖:

// 主窗口代碼

// 監聽來自iFrame的數據推送
window.addEventListener("message", (event) => {

   // 將iFrame推送的數據作同步操做
   store.dispatch(STATE_SYNC, event.data);
});


store.subscribe((mutation, state) => {

    // 這裏咱們要避免出現死循環,忽略掉來自 THREAD_STATE_SYNC 的提交
    if (mutation.type.includes(THREAD_STATE_SYNC)) return;
    
    // 主窗口數據變更時同步至iframe
    iframe.contentWindow.postMessage(state);
});

複製代碼
// iframe 代碼


window.addEventListener("message", (event) => {

   // 將iFrame推送的數據作同步操做
   store.dispatch(STATE_SYNC, event.data);
});


store.subscribe((mutation, state) => {

  if (mutation.type.includes(THREAD_STATE_SYNC)) return;
  
  // 副線程發送
  window.parent.postMessage(state);
});

複製代碼

至此,咱們完成了主窗口到iframe的數據自動同步,保證了數據的一致性同時,儘量的模擬了移動端的真實特性,爲咱們的H5可視化編輯器打好基礎,下一期我會開始講如何實現UI組件庫和可視化編輯器解偶,實現無痛迭代UI組件庫和最大化複用UI組件

下一期

深刻解析 H5 可視化構建工具原理(二) 如何實現外部組件註冊機制

最後

第一次正兒八經的寫文章,可能想表達的東西沒寫清楚,有問題你們能夠在評論區留言,順便最近在找工做,有在杭州濱江附近好的就業機會請聯繫個人微信:wxdreams,十分感激

相關文章
相關標籤/搜索