1、引言
本文將會從總體上介紹 vivo 商城在前端維度的多端統一探索和實踐。javascript
從多端價值、爲何要作多端統1、如何知足多端業務需求、實踐與創新,簡潔直白的闡述咱們在多端統一上所作的一切。css
2、多端探索爲vivo商城帶來了哪些價值
多端的價值能夠從技術架構升級和人力資源釋放兩個方面體現。前端
一、技術架構全面升級
從vue
到java
咱們實現了技術架構方案的統一。經過統一,極大的下降了開發成本、維護成本。同時具有高複用、高效率。vuex
二、釋放大量人力資源
技術架構方案的統一,對業務的橫向擴張提供了強大的技術支持和可實現保障。小程序
下圖是使用新的技術架構後的開發人力投入比。微信小程序
從上圖能夠看出,經過技術架構的升級,釋放了可觀的開發資源。讓釋放的開發資源去作更多有價值的事情。設計模式
3、咱們爲何要作多端統一
你們可能會有疑問,那就是多端統一是什麼?api
這裏我先賣個關子,先不談統一,咱們來講說多端一詞。多端是什麼呢?想必你們都能說個八九不離十。
關於多端,我畫了個圖,以下所示:
從上圖能夠看到,線下、pc、wap、APP、微信公衆號、微信小程序等,每個均可以稱爲一個端。知道了多端的含義,如今,咱們再回頭看多端統一。
完整的多端統一,要包含如下幾個方面的統一
- 大前端【前端+客戶端】的多端統一
- 服務端的多端統一
- 業務的多端統一
這裏,咱們只討論前端的多端統一。
從 PC 瀏覽器,到移動端瀏覽器、到 APP 內嵌,再到各個小程序,再到服務端、客戶端。繁榮的生態,猶如百家爭鳴,百花齊放。然而,繁榮的背後,對前端工程師的挑戰,則與日俱增。
咱們承接的端愈來愈多,新的端不斷的出現,如小程序、快應用等。前端工程師陷入了以下套娃陷阱:
- 現有代碼、新代碼要適配新的端開發場景
- 已經適配新的端開發場景的代碼成爲了現有代碼
- 現有代碼、新代碼要適配新的端開發場景
- 循環...
咱們但願解決這種問題,但願作到一套技術架構方案【代碼】,能夠覆蓋如今的端和將來的端。
通俗點說,咱們但願作到以下圖所示的能力:
在這種前端開發背景下,多端統一出現了。它是前端的一個將來趨勢,它也是解決上面套娃陷阱的一劑良藥。
4、如何知足日益增長的多端業務需求
隨着時間的推移,各小程序端業務被逐漸重視起來,尤爲是 vivo 商城微信小程序。
業務方的述求有兩點,以下所示:
第一點:讓現有 vivo 商城微信小程序的核心功能和商城 H5 功能保持一致。
第二點:後續版本迭代,小程序端和 H5 端同步進行。
而現實是:現有的商城微信小程序,其版本迭代已經較大的落後商城 H5 版本了。
咱們用新老版本的小程序購買流程視頻作對比,讓你們有個較爲直觀的感覺。
老版商城小程序:視頻>>
新版商城小程序:視頻>>
從上面兩個視頻能夠看出二者的差別,咱們面臨的挑戰很大。
根據業務方的述求,咱們須要作的事情在解決上面兩點的狀況下,增長一點,共有三點,以下所示:
第一點:在最短的時間內,將商城 H5 的基本功能和流程在微信小程序上實現出來
第二點:在後續小程序端和 H5 端版本功能同步迭代時,作到高複用,高效率。
- 第三點:提早考慮將來其餘端業務場景的落地,作好擴展性、多端複用性。
在業務驅動下,咱們進行了技術調研、demo 驗證、mvp 驗證。最終在綜合考慮下,採用了 uni-app 多端架構來解決上面兩個難點。
這裏提一下,業務驅動的良好模式,大概以下圖所示:
經過業務來推進技術的優化和改變,在反覆應用的過程當中,實時反饋改進,最後回報給業務。在這個過程當中,技術和業務造成了良性閉環。
NOW. 剩下的事情,就是落地實踐了。
5、咱們的多端作了哪些實踐和創新
有句名言是這樣說的:實踐是檢驗真理的惟一標準。誠然,成功者的背後,有你看不見的努力和堅持。
一、實踐
在實踐過程當中,要考慮的因素不少,列舉以下:
- 現有小程序的原生代碼如何轉成多端項目寫法,保證轉換代碼可讀、可控。
- 現有小程序的部分功能邏輯須要完整保留,甚至是小程序原生 api 和邏輯,這些和多端項目如何共存。
- 如何將 H5 的代碼邏輯最大程度的複用到多端項目中。
- 如何優雅將 H5 的各類組件、設計模式、工程化、工具方法適配到多端項目中。
- 等等...
那麼咱們是如何處理這些因素的呢?
咱們能夠用一張圖總體歸納下,以下圖所示:
下面就介紹下咱們是如何處理這些因素的。
二、代碼轉換
現有小程序的原生代碼如何轉成多端項目寫法,保證轉換代碼可讀、可控?
咱們使用的是開源轉換器 miniprogram-to-uniapp 來作的轉換,而後再經過人工,去解決轉換過程當中不匹配的問題。解決方案就是這麼樸實無華,也許你們以爲方案很簡單,可是選擇這個解決方案的背後,咱們作了詳細的評估,包括和該開源轉換器的做者進行了微信交流。在和做者溝通交流的過程當中,咱們知道了該轉換器的過去、如今和將來,在當時的狀況下,這是一個合適且正確的解決方案。
三、代碼共存
現有小程序的部分功能邏輯須要完整保留,甚至是小程序原生 api 和邏輯,這些和多端項目如何共存?
咱們經過對項目進行合理的目錄劃分,來達到自然的隔離,以下圖所示:
咱們把一些如今還不能適配多端的代碼,統一放到 platforms 目錄下。同時,咱們會使用條件編譯來將如今還不能轉換成多端的平臺隔離開。以下圖所示:
四、複用和適配 h5
複用講究的是一個懶字,能直接複用的就果斷複用,不要作二次調整,保證和 H5 高度一致。
適配講究的是一個以不變應萬變,咱們不須要改動 H5 的代碼,咱們只須要爲他們作一個適配層,如適配 H5 路由,一些不兼容的組件,甚至說適配 window.location 均可以。
從上面介紹的解決方案中,咱們能夠體會到,處理這些因素的核心祕訣就是下面兩句話:
第一句:因地制宜,找到平衡。
第二句:提升複用,下降改動。
五、創新
有句話是這樣說的:平凡中孕育着偉大。放在這裏,咱們換個說法,那就是 實踐中孕育着創新。
在實踐的過程當中,咱們解決了不少問題。在解決問題的過程當中,咱們作出了一些使人高興的創新。
- vuex 創新
這個創新來源於一個問題,這個問題的背景以下:
商城 H5 商品詳情頁用 vuex 管理數據,在將 vuex 移到小程序商品詳情頁中時,發現一個現象,以下動圖所示:
從上面動圖中,咱們發現,在使用 vuex 時 ,咱們從 A 商品的詳情頁中點擊 B 商品,進入 B 商品詳情頁。這時,咱們點擊左上角返回 A 商品詳情頁,會發現,此時商品詳情頁已經變成 B 商品,也就是說,A 商品的數據已經沒了。
這是一個很是大的問題,通過排查,發現緣由以下:
vuex 的 namespace 默認是一個,沒法自動新增 namespace 。當在小程序頁面裏面使用 vuex 進行數據管理時,因爲小程序頁面數據機制,在點擊返回時,頁面數據使用的是同一個 vuex 的數據,從而致使了上面出現的現象。
這裏,有人可能要說,在 onShow 生命週期裏面,刷新數據,不就解決了嗎。其實否則,在這種場景下,進行數據刷新是很是不合理的。
那麼該如何解決呢?
咱們知道,小程序頁面數據在使用 vuex 後,屢次進入同一個頁面後,返回會有展現問題。隨後,組內進行了討論,綜合權衡後,肯定繼續用 vuex ,經過給 vuex 加一個適配層來解決這個問題。
隨後,組內進行了討論,綜合權衡後,肯定繼續用 vuex 。經過給 vuex 加一個適配層來解決這個問題。
首先咱們看下,在給 vuex 加一個適配層後,進行上面的操做,會是什麼現象。
以下動圖所示:
從上面的動圖,咱們能夠發現,在給 vuex 加了一個適配層後。成功的解決了小程序頁面數據在使用 vuex 後,屢次進入同一個頁面後,點擊返回時,出現的展現問題。
咱們是如何解決這個問題的呢?
核心方案:經過讓 vuex 支持自動擴展、自動註銷 namespace,來作到更加智能化的數據流管理方案。
核心架構圖以下所示
經過在 store 中自動生成 namespace,保證了同一個頁面進入屢次後,每一個頁面數據都是保留的。當頁面返回時,經過動態收集父組件的 namespace ,完成了父子組件的 namespace 關聯。
經過上面的技術方案,咱們解決了 vuex 在小程序裏面使用時,存在的問題。這裏,核心架構方案已經給出,具體實現,就再也不細述了。
六、解耦創新
這個創新來源於一個問題,這個問題的背景以下:
咱們如今有普通、 秒殺 、 拼團 商品詳情頁,後面還會有其餘商品詳情頁,那麼咱們如何複用這些詳情頁裏面的業務組件呢?
面對上面的問題,你們會有如下思考:
-
不一樣頁面,業務組件內的數據處理是有差異的
-
不一樣頁面,業務組件內的埋點是不同的
- 不一樣頁面,業務組件內可能存在特定的接口請求
上面的這些思考,你們看過應該是有感觸的,複用業務組件自己就是一件很困難的事情,若是想完全的解耦更是難上加難。
那麼,咱們是如何作到儘量解耦的呢?
咱們作了如下幾點:
- 在上游保證埋點統一,經過設計組件層面的埋點來達到埋點統一。
- 在組件層面,對特定接口,進行條件判斷。
- 將業務組件的數據分解成源數據和派生數據,源數據在 vuex 層面保證一致,派生數據在業務組件內根據實際狀況進行相應的適配。
- 對 vuex 進行改造,讓業務組件和頁面的通訊完全解耦,業務組件再也不須要知道頁面的 vuex 命名空間。
開發過商城項目的同窗應該都清楚已選彈層的邏輯是很複雜的,這裏就拿 已選彈層 業務組件作例子來講下咱們是如何去作業務組件複用的。
下面是目前已經複用的已選彈層組件的組成:
├── components │ ├── sku-number │ ├── sku-product │ ├── sku-service │ ├── sku-spec │ └── ... ├── index.js ├── index.scss ├── index.vue ├── mutation-types.js └── track.js
咱們將已選彈層組件的數據分爲源數據和派生數據,源數據經過 vuex 層面去統一,以下圖所示:
咱們爲每一個詳情頁寫一個 vuex ,同時將相同的部分抽離到 common-detail 中。以後,咱們在 vuex 中進行處理,保證不一樣頁面給出的源數據是相同的。這些源數據是要傳到業務組件中的。
以下代碼所示:
// 這是已選彈層業務組件 // 經過 @vivo/smartx 解耦組件和頁面的通訊 import { mapState, mapGetters, mapMutations, mapActions } from '@vivo/smartx' // 獲取源數據 computed: { ...mapState([ 'spuInfo', 'skuInfo' ]), ...mapGetters([ 'price', 'pageType' ]), } methods: { fn() { // 策略模式 } }
經過上面的處理,就能夠將相似的業務組件很好的從不一樣頁面中解耦出來,從而提升代碼的複用性、可維護性以及可擴展性。
這種解耦業務組件的思想就在於:
沒必要刻意將數據與視圖完全分離,經過源數據和派生數據,平衡好變和不變的數據,再經過自研的 @vivo/smartx 將變到不變變成孤島,將不變到變變成孤島。
每一次創新,都是一次考驗,它老是不經意間給你出難點,而後逼迫你,去突破本身,從而創造出更好的東西,循環往復。
最後,多端架構的 vivo 官方商城微信小程序已經上線了。你們能夠點擊vivo官方商城體驗一下哦。
6、總結
本文咱們一塊兒回顧了, vivo 商城微信小程序的多端統一之路。從業務須要,存在價值,到技術實踐與創新,咱們但願用技術讓多端之路可以更加平坦。
vivo 官網商城前端團隊