Vue3多端項目實戰——開發一個多端音樂 APP我踩了很多坑!

語言: CN / TW / HK

項目背景

先來聊聊為啥要搞這個玩意?有以下幾個方面的原因吧:

  1. Vue3 已經發布很久了,公司還沒有積極擁抱 Vue3,筆者還停留在看Vue3文檔階段(看文檔的效果還是沒有以實際項目推動來得快,畢竟看完刷刷短視頻就忘了🌝),所以想做個個人項目積累經驗。
  2. 女朋友吐槽,QQ 音樂、網易雲音樂廣告很多,Apple Music 個性推薦又不太懂我的個性。
  3. 筆者畢業之後一直在搞 PC 端的項目,沒有移動端項目經驗。

基於上述三點,這個項目就正式立項了。

技術選型

  • 技術棧沒得説了,擁抱 Vite、Vue3
  • 沒有多端經驗,那就用 uni 吧,我倒是要看看是不是像吹得那麼牛逼
  • 全局狀態管理沒的説 pinia
  • 路由就不需要了,畢竟小項目嘛,邏輯不太複雜,頁面也不多,就不用 VueRouter 了,整個動態組件就 OK
  • i18n 也不需要了,項目簡單,用 pinia 也能玩
  • css 擴展——sass, 抽離 css 變量,維護更方便
  • UI 組件庫就不用了,uni 內置組價夠用,別的就自己封裝吧
  • 圖標 iconfont 找了一套字體圖標
  • 圖片素材也是 iconfont 找的
  • logo 來自 標小智, 輸入關鍵字會生成很多可選的 logo,然後需要付費下載,付費是不存在的!直接給水印去掉,再利用 Chrome 的 screenshot 拿到圖片(清晰度不好,再找個網址修復下,哈哈)
  • UI 方面,我直接抄了 Apple Music 和 網易雲音樂 的作業😄

最重要的——音樂來源

音源來自開源項目NeteaseCloudMusicApi,網易雲音樂的音源。沒踩到坑,文檔非常給力,唯一的不足就是 查詢我喜歡的音樂接口 不支持分頁查,一次性就全搞回來了。

封裝組價梳理

在項目中,我封裝了很多基礎組件 和 業務組件。

基礎組件

| 組件 | 組件用處 | | --- | --- | | NoData | 無數據組件 | | NoLogin | 未登錄組件 | | Message | 提示消息 | | Loading | 數據加載中組件(h5是指令,小程序不支持指令) | | LazyLoader | 圖片懶加載組件 | | PageFrame | 頁面容器組件,向下滾動標題吸頂,滑到底部加載更多數據 | | Process | 進度條組件 |

業務組件

| 組件 | 組件用處 | | --- | --- | | SongListItem | 歌曲條目組件 | | SongSheet | 歌曲組件 | | Category | 歌單列表 | | Search | 搜索組件,防抖處理 | | Player | 播放器組件 | | MySpace | 我的 | | Recommend | 推薦頁 | | ...... | ...... |

亮點

  • 擁有 Apple Music 的顏值,玻璃擬態風格
  • 簡約大氣、無廣告
  • 輕量 打包後體積一共 316kb,運行在 Chrome 後 memory 大概 7M 左右,加載的數據多了會大一些
  • KeepAlive 實現組件緩存
  • 異步加載組件 按需加載
  • 多端適配(wx 小程序、PC)
  • 網易雲掃碼登錄(PC 很方便;小程序需要截圖再掃碼,沒有找到對接微信登錄的接口🙁)
  • 暗黑模式適配
  • 按照顯示寬高請求圖片,不讓瀏覽器去縮放,提升性能

適配PC 和 手機 & 暗黑模式

為啥要説這個呢,我就是想表達一點,我們在開發時,將與主題相關的變量一定要抽出來,最後去做適配你會發現事半功倍的效果。

image.png

暗黑適配:沒有使用 uni提供的方案,不喜歡配置,喜歡自己玩。 image.png

你沒看錯,就是那麼幾行!為啥要加 !important,因為 uni 默認給 style 加了 scope,導致優先級沒有默認的樣式高。

用 pinia 實現多語言

因為語言變量不多,我決定不用 i18n,將語言加載到全局狀態管理即可: image.png

image.png

組合式函數抽離公共代碼

請允許我説一聲 Vue3 牛批! 項目組有兩個地方都有 播放、暫停、下一曲、上一曲按鈕,此時就該 組合式函數 上場優化代碼了(一開始是複製的,最近才優化了😂)

image.png

使用:

image.png

部署相關

界面展示

推薦頁

PC

image.png

wx小程序

我的

PC

image.png

wx小程序

歌單頁

PC

image.png

wx小程序

歌曲列表

PC

image.png

wx小程序

播放器界面

PC

image.png

wx小程序

聊聊開發中遇到的坑

因為筆者沒有移動端開發經驗嘛,所以一路還是踩了不少坑,主要就是兼容性的問題,接下來我就詳細和大家聊聊。一開始選擇 uni 就是以為 uni 幫我們支持多端做了很多東西,能讓我使用 h5 vue 的開發模式自動的就兼容了。所以想都沒想,就開始用瀏覽器的移動設備模擬調試,一直都很順利。

然後到了一個節點想着放到真機上跑一下,把流程跑通。用的蘋果手機嘛,就想着能不能搞成App 跑一下啊,然後看 uni 的文檔,需要一個蘋果的 appid,所以就去註冊了 Apple Developer Program,這破玩意要不就是登不上,要不就是註冊不成功,對象的號都試了,後來看到還要收費,打擾了,破玩意,浪費時間!

還是選擇 wx 小程序吧!這個比較容易,只不過跑起來後控制枱報了一堆錯誤,這也不支持,那也不支持,樣式也都不對!此時心中萬馬奔騰,靠!説好的 "一套代碼,多端運行"?

image.png

經過我在 uni 文檔的一番搜索瀏覽,我發現人家説的一套代碼是需要這樣的: image.png uni 文檔中是這麼説的:

uni-app 已將常用的組件、JS API 封裝到框架中,開發者按照 uni-app 規範開發即可保證多平台兼容,大部分業務均可直接滿足。

意思就是我用到的都是不常用的,所以需要自己寫各端的實現才能跨端唄!好的我懂了,是我不會用 uni。於是我這就這樣了: image.png 後續開發都是先實現任意一端,再將代碼 cherry-pick 到另一個分支做一些選擇性的合併。我也不知道我為啥要這麼做,就當成強迫症吧!

好了接下來就聊聊具體的坑。

不支持指令

這個可能是移動端沒有 dom, 而指令是操作 dom 的。所以全局 Loading 在 h5 是通過指令實現,小程序是封裝成組件。

不支持 defineAsyncComponent

PC: image.png 小程序: image.png 不能使用 KeepAlive,那就只能緩存請求數據了。

IntersectionObserver問題

在實現下拉標題吸頂,下拉到底加載更多需要用到這玩意,PC沒啥問題很好用, 我在這邊文章中專門寫了下:也許這是Vue3最簡單的懶加載方案了(適用圖片/組件)

小程序就很坑了: image.png 不能使用 script setup,因為在小程序端通過 uni.createIntersectionObserver 創建observer 實例,必須傳入 this,否則監聽無效(坑死個人🤢)

樣式問題

小程序不支持挺多選擇器

比如: css [class^=icon]{ }

css變量

css // pc :root { --global-bg: rgba(0, 0, 0, .9); --global-color: rgb(255, 255, 255); --bottom-bar-color: rgb(106, 106, 106); --bg: rgba(15, 15, 15, 0.6); --message-bg: rgba(15, 15, 15, 0.9); } // wx小程序 page { --global-bg: rgba(0, 0, 0, .9); --global-color: rgb(255, 255, 255); --bottom-bar-color: rgb(106, 106, 106); --bg: rgba(15, 15, 15, 0.6); --message-bg: rgba(15, 15, 15, 0.9); }

寬高繼承問題

image.png

目前印象比較深刻的點就這些吧!

體驗一下吧

體驗地址: - PC:LVMusic - wx 小程序:

總結

通過本次實戰,對移動端開發有了一個大概的認知: 1. uni 配置太多,有些坑文檔沒寫清楚,上手學習成本還是不小,可能是因為我不看文檔就開發,遇到問題才知道看文檔。 2. 如果不熟悉的話,移動端開發會花很多時間在適配上 3. Vue3 組合式的語法真的很香 4. pinia 比 Vuex 更易用 5. 組合式函數抽離公用邏輯真的很牛批👍🏻 6. 等等......