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. 等等......