本專案主要是為了熟悉快應用而練手的專案,該專案資料基於豆瓣api V2,簡單的實現了電影、圖書、音樂的預覽功能。雖說快應用基於類似前端的html、css、js語法來編寫程式碼的,但是使用時並沒有那麼好用,很多東西都沒有得到支援。
前言
按照官方文件所說的,建議使用node v6.11.3版本,不要使用node 8.0以上版本,而我本地的node版本正是8.0以上的。所以就使用了nvm來管理node的版本,使用nvm切換node版本非常方便,關於nvm詳情請自行google。我的程式碼就是在node 6.11.3上執行的,所以建議執行我程式碼也在node 6.11.3上。
簡介
說到快應用,一般會拿來跟小程式做對比,就目前的api功能,debug能力,css屬性支援等與小程式相比還是有一點距離。不過快應用是直接呼叫的系統api,所以流暢度還是蠻不錯的。不管怎麼說,畢竟快應用剛剛推出,希望它變得越來越好。
關於專案的搭建、執行、熱載入、devtool除錯,官方文件寫的非常詳細,而且也有很多人也寫了入門demo和教程,我看了一下,大部分就是copy的官方文件。所以這裡不做過多描述,多看官方文件吧。
通過這個專案,熟悉了一下快應用的基礎元件使用,列表渲染,tab切換,api介面呼叫,頁面傳參,自定義元件的構建等。在使用中也遇到一些坑,再次記錄下,我也是新手上路,也只用到部分功能,文章難免有不對的地方,歡迎大家指正。
說一下實現的功能:
本專案主要實現了電影、圖書、音樂三個模組。每個模組都有三個類別,通過tab切換來檢視不同類別。(比如圖書有小說、歷史、傳記三個類別。)三個模組的ui展示都一樣。主要使用了list實現了列表滾動,tab切換、refresh下拉重新整理,資料懶載入等功能。每個模組都有一個詳情頁展示詳情資訊。首頁有個測選單欄,預設收起狀態,通過點選選單彈出選單跳轉到不同選單頁。選單頁主要有主頁,主題頁和關於頁面,整個專案很簡單。
下面就幾個我認為重要的點說一下:
1、封裝fetch資料請求
每個新的環境下我第一個封裝的一般是網路請求。翻看了一下文件,支援async、await,果斷引入,遠離令人頭疼的callback hell。文件說的很清楚,使用async,要引入babel-runtime/regenerator。所以在app.ux中首先引入。fetch通過async改造,同時結合豆瓣api V2對返回資料過濾後返回出來。並且封裝了常用的get、post請求,並把封裝的network物件暴露在全域性,在所有檔案中可以直接使用不用引入,詳情請看程式碼。
2、封裝自定義元件
我封裝了一個評分元件和一個封面展示元件,和一個頭部元件。這三個元件是純渲染元件,沒有什麼邏輯的。同時做了一個列表元件,因為三個模組都是採用相同列表,列表元件通過傳遞的不同url來呼叫不同介面渲染列表。列表元件主要參考的官方文件,使用了資料懶載入,文件上寫的很詳細。同時也使用了tabs元件,refresh元件來實現橫向滾動和下拉重新整理。本來是準備進一步封裝一個容器元件來完成這些功能的,但是看到自定義元件裡slot只支援一個,不像vue那樣可以命名slot。所以就放棄了做容器元件。
3、實現了一個抽屜效果的側邊欄選單。
剛開始專案時就打算要實現一個模組來放個人資訊,換膚的功能,本來打算模仿微信的,放在底部選單,多一項叫做我的。由於我是網易雲控,就打算模仿一下網易雲,做個測邊欄選單,並且還有抽屜的滑入滑出效果,想看一下快應用上怎麼實現動畫。按照前端習慣,一上手就transition屬性搞起,發現不支援,於是立馬檢視文件,只支援animation,並且屬性要分開寫。animation實現動畫沒有transition這麼方便,開啟和關閉要分別用不同的動畫來實現,通過js修改class屬性來實現不同的animation。但是有個蒙版,要在抽屜開啟動畫開始時開啟,抽屜關閉動畫結束後關閉。所以通過一個變數繫結style屬性。在動畫開始時立馬顯示。動畫結束沒法監聽,只能通過定時器來實現。
4、換膚功能。
實現了一個簡單的換膚功能,通過全域性儲存一個變數,通過改變變數來實現換膚功能。改變資料後,進入新頁面,頁面讀取全域性資料,載入頁面就能正常切換皮膚,可是如果改變頁面後當前頁面的皮膚怎麼變化呢?看到文件裡有個$watch函式,可以監聽屬性變化,於是在需要實時切換膚色的頁面定義一個變數,讀取全域性變數賦值給當前變數。再用$watch來監聽該變數變化來實現實時換膚。但是當改變全域性變數時,當前頁面變數怎麼會實時改變呢?對於一個原始型別的資料,當然不可能達到監聽效果,這時只能通過物件來實現這一功能了。因為物件賦值會引用同一地址。所以可以實時監聽資料變化。
需要注意的問題及坑:
1、除錯相關
1、雖說快應用可以用谷歌的devtool的debug功能,但是其與谷歌debug差太多了。首先沒有network模組,網路請求資訊都看不到。其次在程式碼中的console.log輸出的物件型別資料都會呼叫Object.prototype.toString方法轉換成字串。為此很頭疼,每次獲取的資料要呼叫JSON.stringify轉換為json字串輸出,再將json轉換成物件檢視,很雞肋的功能,有時一呼叫介面遠端除錯就閃退。
2、雖說是熱更新,但是有時還是要手動重新啟動專案才能達到預期效果,比如:新增了新檔案。在manifest.json中修改不會熱更新,要切換到其他頁面儲存。有時manifest.json中修改儲存後也達不到預期效果,也要重啟專案,比如頭部欄樣式。
2、基礎元件相關
1、與小程式一樣,快應用裡的基本元件都是封裝好的,只能用文件裡提到的基本元件,而不是普通的html標籤都能使用。每個元件的盒模型都是採用的box-sizing: border-box並且不準修改。這一點符合我們習慣,平時移動端專案也都是採用這種盒模型。
2、還有預設容器元件,比如我們用的比較多的div元件,其預設排列方式類似css中的行內塊元素一樣,而不同於html中div的塊級元素。預設橫向排列,要想縱向排列只能設定外層容器flex-direction為column。
3、對於自定義元件,在元件內最外層元素設定了class屬性,在引入元件時,在元件上也使用class時,元件裡的class屬性會被覆蓋,並不會疊加。
3、css相關
必須吐槽的是css的樣式支援。太多的樣式屬性在裡面都不支援,寫起來一點也不爽。關於支援哪些css,可以看官方文件,寫的很清楚。對於不支援的css在編譯時會報紅提示你不支援。
1、比如我在寫樣式寫的正(。・∀・)ノ゙嗨時,突然發現沒有達到預期效果,看了一下編譯報錯,不支援position: relative, absolute等屬性,瞬間頭疼,這不是很常用的樣式,不支援?那快應用怎麼實現這樣效果了?翻看了一下文件,發現了一個容器元件stack元件,放在裡面的子元素從上到下層級越來越高。這隻實現了層級,怎麼定位呢?當然是配合另外一個樣式屬性:translate同個這個屬性可以上下左右移動來實現定位。上帝給你關上一扇門時,也會給你開另一扇窗,多看文件,騷年?。
2、而且position支援fixed定位但是不支援z-index來調節層級,只能通過元件先後順序來定層級。
3、普通容器不支援橫向滾動,沒有overflow的屬性,只能通過tabs來hack。
4、動畫不支援transition,只能通過animation來實現。
4、對於js部分
1、自定義元件引入後在上面加事件能正常監聽,但是給監聽函式傳遞引數,監聽函式不能獲取到。
2、基礎元件的通用事件不知是否存在類似event這樣的物件,只知道存在一個物件,但是列印為object型別,呼叫JSON.stringify函式會報錯。
3、props不支援預設值,如果要預設值只能通過$watch來監聽prop值的改變來自定義一個data屬性。
4、繫結的通用事件會冒泡,但是沒有提供阻止冒泡的方法,但是隻會冒泡到最近一層包含監聽該事件的元素上而不會繼續向上冒泡。故可以通過繫結一個空函式來阻止事件冒泡。
5、在頁面元件中可以通過this.$app和this.$app.$def這兩個物件呼叫掛載到app.ux裡的屬性。但是注意:
app.ux中掛載的所有屬性在this.$app.$def中都能獲取到。但是隻有方法屬性會掛載到this.$app上。
6、refresh元件在使用時可以通過refreshing來切換當前狀態,但是手動觸發refresh事件時,refreshing並不會變為true,重新整理結束後將其設定false並不能結束重新整理狀態。所以要同步設定refresh的狀態,在refresh事件中將refreshing手動設定為true,待重新整理結束後再將其設定為false,才會結束重新整理狀態。
7、引入元件中的資源引入路徑是基於當前引入的元件。比如在元件中有個靜態圖片資源,我在元件裡寫死路徑,當其他頁面元件引用該元件時,會報找不到該資源的錯誤。必須將元件裡的資源路徑改為當前頁面相對圖片的路徑,這顯然有問題。不同頁面引入資源路徑當然有可能不同,只能通過props傳遞進去。
專案展示
前方多圖預警。。。
關於專案的任何問題,歡迎一起討論!!!
放出專案地址:
歡迎star #^_^#