項目總結:vue.js2.5餓了么APP(1)概述+項目准備
一、概述
1. 項目簡介
使用vue.js vue是當前最火的MVVM框架,(優點:輕量、簡潔、高效、數據驅動、組件化)
本項目做的是:高仿上線外賣APP商家模塊
開發過程:需求分析-腳手架工具-數據mock-架構設計-代碼編寫-自測-編譯打包
以線上生產環境來開發:代碼開發及測試環節:UI標注完美還原設計圖、以真實外賣APP數據做演示,以保證代碼無兼容性問題。
代碼規范:(1)架構設計;(2)組件抽象;(3)模塊拆分;(4)代碼風格統一;(5)JS變量命名規范;(6)CSS代碼規范;致力於編寫高可維護,易於擴展,通用性強的代碼,了解真實項目流程。
2. 功能技術分析

一期
(1)Vue-resource和后端做數據交互,
(2)使用Vue-router做前端路由實現單頁面應用,
(3)使用第三方庫better-scroll來實現列表滾動,
(4)最大程度組件化(頁面上有很多樣式和功能相似的區塊,方便在項目中復用),
(5)商家頁面中,收藏商家這個功能會使用html5的localstorage接口,存儲在瀏覽器端,
(6)對於圖標字體的應用,
(7)移動端1像素邊框,
(8)css sticky footer布局,
(9)flex彈性布局。

二期
技術棧:vue.js 2.5.17 vue-cli 3.0 cube-ui
(1)Vue.js高級知識(組件封裝,組件通信,插槽,過渡動畫,mixin)
(2)對於vue-cli3.0腳手架的應用(不僅用來初始化項目和開發調試,還做一些額外的webpack配置,並且利用它來mock數據,在項目完成之后還會做打包構件分析);
(3)充分利用cube-ui的七個組件和一個模塊(使用第三方開源組件庫)
3. 學習內容
學習目標:(1)掌握vue.js在實戰中的運用;(2)學會使用Vue.js完整開發移動端APP;(3)學會組件化、模塊化的開發方式;(4)學會使用第三方組件庫輔助開發;(5)學會項目部署和構建過程
學習內容:(1)Vue.js框架介紹;(2)vue-cli腳手架搭建基本代碼框架;(3)vue-router官方插件管理路由;(4)vue-source ajax通信;webpack構建工具;(6)ES6+eslint 規范代碼風格,代碼風格審查工具,靜態語法檢查。
移動端常用開發技巧:(1)flex彈性布局;(2)css stickyfooter布局;(3)炫酷的交互設計;
4. 近年來前端開發趨勢
(1)舊瀏覽器逐漸被淘汰,移動端需求增加(IE6-8不支持ES5特性)
(2)前端交互越來越多,功能越來越復雜(高大上的技術庫和框架,酷炫的運營活動頁面,H5小游戲,新聞趣味站,在線購物平台,社交網絡,金融信貸應用,音樂互動社區,視頻分享平台,打車出行平台)
(3)架構從傳統的后台MVC向REST API + 前端MV*(MVC MVP MVVM)遷移(使用ajax方式,和后端REST API通訊,異步刷新頁面的某個區塊,來優化和提升體驗)
5. MVVM框架
Model 是數據部分,對應到前端就是JavaScript對象;View是視圖部分,對應前端的DOM,ViewModel就是連接視圖和數據的中間件。
在MVVM的架構下,數據和視圖是不能夠直接通訊的,通常通過viewmodel做通信,viewmodel通常要實現一個observer觀察者,當數據發生變化,viewmodel能夠觀察到數據的變化,然后通知到對應的視圖做更新,而當用戶操作視圖,viewmodel也能監聽到視圖變化,然后通知數據做改動,這就實現了數據的雙向綁定。

應用場景:針對具有復雜交互邏輯的前端應用;提供基礎的架構對象;通過Ajax數據持久化,保證前端用戶體驗。
(當前端和數據進行操作的時候,可以通過ajax請求和后端做數據持久化,不需要刷新整個頁面,只需要改動DOM里面需要改動的部分,特別是移動端應用場景,刷新頁面的代價太昂貴,會重新很多資源,雖然有些資源會被緩存,,但是頁面的DOM,JS,CSS都會被重新解析一遍,因此移動端頁面都會做成SPA單頁面應用,因此誕生了很多SVVM框架,如angular.js, react.js, vue.js)
6. 什么是vue.js
(1)它是一個輕量級MVVM框架;
(2)數據驅動+組件化的前端開發
(3)GitHub超過25k star,社區完善
對比Angular 和React
vue.js更加輕量,gzip后大小之后20K+,因此對於移動端來說vue更加適合;
vue.js容易上手,學習曲線平穩;(angular入手較難)
吸收兩家之長,借鑒angular的指令和react的組件化;
Vue.js的核心思想

(1)數據驅動:DOM是數據的一種自然映射
如果沒有Viewmodel是如何交互的?視圖改變會手動觸發DOM改變。
使用了Vue.js之后,就省去了手動操作DOM的步驟,在vue.js中只用改變數據,vue.js通過Directive指令,對DOM進行封裝,當數據發生變化,會通知指令修改對應的DOM,數據驅動DOM變化,DOM是數據的一種自然映射。Vue.js還會對操作做一些監聽,當我們修改視圖的時候,vue.js監聽到這些變換,從而改變數據,這樣就形成了數據的雙向綁定。
數據響應原理:數據改變驅動視圖更新。
有一份數據a.b,在一個vue對象實例化的過程中,會給b通過object。Defineproperty屬性添加了getter和setter,同時vue.js會對模板進行編譯,解析生成一個指令對象v-text指令,每個指令對象都會關聯一個watcher,當我們對對應的表達式a.b求值的時候,就會觸發getter,把依賴收集到watcher里面。當再次改變a.b的值的時候,會觸發setter,會通知到對應的watcher,watcher會再次對a.b求值,計算對比新舊值,當發現值改變,watcher會通知到指令,使用指令的update方法,由於指令是對DOM的封裝,所以就會調用原生DOM的方法更新視圖,這樣就完成了數據改變到數據更新的一個自動化的過程。

(2)組件的設計原則:頁面上每個獨立的可視/可交互區域視為一個組件;每個組件對應一個工程目錄,組件需要的各種資源在這個目錄下就近維護(前端工程化和分治思想);頁面不過是組件容器,組件可以嵌套自由組合形成完整頁面。
7. cube-ui組件庫
- Popup 彈層:底層彈層組件,主要用於基於此組件實現上層組件封裝,只提供了基礎功能:指定類型、是否有背景層、顯示內容(HTML)以及是否居中。
- 內置所有的彈層類組件都是基於此組件實現,包括:Toast、Picker、TimePicker、Dialog、ActionSheet。
- Scroll 滾動:滾動列表,提供了優質的原生滾動體驗,便捷的配置項和事件,是一個基於better-scroll進行封裝的組件。
- Slide 幻燈片:輪播圖,提供了常見的輪播及swipe的功能,也是一個基於better-scroll進行封裝的組件。
- IndexList 索引列表:索引列表,提供了列表索引的功能,也是一個基於better-scroll進行封裝的組件。
- create-api:有些時候,開發者可能也需要自己封裝的組件支持 API 式調用,此時可以通過引入 create-api 模塊或者通過全局的 Cube.createAPI 接口來達到封裝目的。
- Dialog:Dialog模態框組件,提供了多種樣式及交互形式。
二、項目准備
1. 需求分析
1)區塊划分
6張設計稿;區塊划分為:頭部區、內容區(商品頁、評論頁、商家詳情頁)


點擊導航欄會進行切換,由於是SPA單頁面應用--切換頁面時不會刷新整個頁面;
(1)頭部區:包括商家描述,當點擊公告和數字的時候會展示黑色的浮層,點擊按鈕浮層關閉;
(2)內容區
商品頁:可以拆分為左右兩欄,左側是商品的分類,右側是實際商品的列表。當商品區塊對應某個分類時,左邊導航欄相應分類會高亮,當列表內容超過頁面可視區塊時,可以進行滾動,在滾動右側時,左側的高亮區也會保持聯動的效果。商品頁底部是一個購物車,當點擊加號購買商品的時候,購物車會聯動購買的商品總數和金額,當金額超過最小配送費時,顯示“去結算”按鈕,點擊按鈕可以進行結算;當購物車商品部位0 時,點擊購物車是沒有反應的;點擊購物車會彈出購物車列表,列表也有最大高度,當超過最大高度,內部可以滾動,在購物車內部也可以進行添加和刪除操作,並且和主頁面保持聯動。當我們點擊具體的商品,會展示具體商品頁浮層,有商品圖片、介紹,可以點擊加入購物車,一樣可以完成一次購買流程,底部是一個評論區,我們可以條件查看,比如根基評級類型(有無內容)進行勾選,評論區的顯示會相應做出變化,當浮層頁面超過手機高度時,頁面可以滾動,頁面左上角有一個返回按鈕,點擊按鈕浮層會關閉。
商品評論頁:上面是一個評星級別,下面是具體的評論區。
商家詳情頁:主要是商家信息的展示,商家實景圖是當圖片官渡超過頁面寬度時可以左右滾動,當整個頁面超過手機高度,可以上下滾動,有一個收藏區塊,可以點擊收藏關注商家。
2)組件拆分
由於是組件化的開發,整個頁面可以看成App.vue一個大組件。
大組件包含頭部(header),導航區(主要控制下面內容部分的切換),內容部分包含商品(goods),評價(ratings),商家(seller)三個組件。
2. 圖片素材
1)設備像素比
移動端一張圖片需要2x和3x,來適應不同dpr(device picture ratio設備像素比)推薦文章:張鑫旭-設備像素比簡單介紹
https://www.zhangxinxu.com/wordpress/2012/08/window-devicepixelratio/
參考鏈接:https://www.cnblogs.com/samwu/p/5341056.html
2)SVG圖片
SVG是一種矢量圖片,它的特點就是當我們把它放大之后圖片質量不會下降,在移動端開發過程中,通常會把一些色彩單一的圖片做成SVG圖片,在CSS中引入圖標字體文件。
推薦IcoMoon工具: https://icomoon.io/
網站具體使用方法:點擊Icomoon app按鈕,會跳轉到如下頁面,點擊Icomoon icon按鈕,之后選中所有的SVG文件;選中自己想要的圖標后,點擊右下角的generate font,可以查看代碼。點擊preference可以修改字體名稱等;點擊download按鈕,解壓后fonts里面就是所有的圖標字體文件以及style.css。

3)support-ico組件對圖標處理
由於項目中的圖標(icon)多次使用,並且尺寸(1,2,3,4,四種尺寸)和類型(減、折、特、票),基於此,就不同把這些圖標做成一個組件support-ico。
<template><span class="support-ico" :class="iconCls"></span></template>
含有一個動態綁定的class,可以根據傳入的props(size,type)改變綁定的class。
Computed計算屬性icon Cls(),定義一個數組,數組保存了{'decrease', 'discount', 'special', 'invoice', 'guarantee'},可以根據傳入的type和size動態拼接icon的樣式。
-
computed: {
-
iconCls() {
-
const classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee']
-
return `icon-${this.size} ${classMap[this.type]}`
-
}
-
}
實現對於不同的類型和大小引入不同的圖片。
3. mock數據
准備了一個data.json里面是我們模擬的數據。包含三個部分:seller,goods,ratings
在vue.config.js中寫入devServer字段,並且有一個before函數,可以通過app.get來模擬get接口,返回json字段,其中goods,ratings,seller都是通過data.json字段拿到的。

測試:啟動服務之后輸入localhost:8080/api/seller會返回json數據。表示mock服務成功了。
4. 使用vue-cli搭建項目框架
安裝並創建項目,參考鏈接: https://cli.vuejs.org/zh/guide/installation.html


項目入口html在public目錄下的index.html, index.html編譯之后會引用main.js(入口js是src目錄下的main.js)
.browserslistrc 瀏覽器,用CSS在不同瀏覽器可能存在兼容性問題,因此需要對其加前綴---針對於postcss.config.js中的autoprefixer插件()
Eslintrc.js就是eslint的配置
Package.json就是需要的依賴,項目描述
5. 安裝cube-ui
移動端比較好用的組件庫https://didi.github.io/cube-ui/#/zh-CN

Theme.styl 列出所有組件的顏色,可以進行修改
Package.json中添加了一個transormModules字段,引用cube-ui組件
Vue.config.js 可以進行額外配置
6. 項目common目錄

1)fonts
存放SVG相關圖片的信息
2)stylus
Index.styl 入口文件,里面import icon和base(在main.js需要引入index.styl)
Icon.styl是字體圖標的樣式(引用了font下面的文件,制作的圖標可以通過類名可以訪問到icon)
Base.styl定義了基礎樣式(html和body)
mixin.styl導入了cube-ui的stylus(@import "~cube-ui/src/common/stylus/mixin.styl")
Variable.styl導入cube-ui的一些變量(@import "~cube-ui/src/common/stylus/variable.styl"),同時自己定義了項目的顏色
7. axios封裝和數據獲取
Axios第三方庫獲取數據:https://github.com/axios/axios
npm i axios --save
在目錄下創建api-helper.js和index.js,對於所有的get方法進行封裝
-
/*helper.js*/
-
import axios from 'axios'
-
-
const ERR_OK = 0
-
-
export function get(url) {
-
return function(params) {
-
return axios.get(url, {
-
params
-
}). then((res) => {
-
const { errno, data } = res.data
-
if (errno === ERR_OK) { // 成功
-
return data
-
}
-
}). catch(() => {
-
})
-
}
-
}
-
/*index.js*/
-
import { get } from './helpers'
-
-
const getSeller = get('/api/seller')
-
const getGoods = get('/api/goods')
-
const getRatings = get('/api/ratings')
-
export {
-
getSeller,
-
getGoods,
-
getRatings
-
}
8. 1像素border實現
border-bottom: 1px solid rgba(7, 17, 27, 0.1)
在PC端是1像素邊框,但是在手機端有設備像素比,所以可能看上去會有不同
設計一個mixin.styl
-
border-1px($color)
-
position: elative
-
&:after
-
diaplay: block
-
position: absolute
-
left: 0
-
bottom: 0
-
width: 100%
-
border- top: 1px solid $color
-
content: ' '
對於需要添加1像素邊框的標簽加上border-1px類,然后對偽類進行縮放
-
@media(-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)
-
.border- 1px
-
&::after
-
-webkit-transform: scaleY(0.7)
-
transform: scaleY(0.7)
-
@media( -webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2)
-
.border- 1px
-
&::after
-
-webkit-transform: scaleY(0.5)
-
transform: scaleY(0.5)
1像素border實現:偽類(絕對定位)+ 縮放(對偽類Y軸縮放),
另一種思路是在html的header里添加如下一句:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
參考連接:https://www.cnblogs.com/wisewrong/p/6425315.html
https://www.jianshu.com/p/fa670b737a29
后續章節傳送:
項目總結:vue.js2.5餓了么APP(2)主要組件實現 - 頭部相關組件
項目總結:vue.js2.5餓了么APP(3)主要組件實現 - 購物車相關組件(上)
項目總結:vue.js2.5餓了么APP(4)主要組件實現 - 購物車相關組件(下)
項目總結:vue.js2.5餓了么APP(5)主要組件實現 - 商品詳情頁部分
項目總結:vue.js2.5餓了么APP(6)主要組件實現 - 評價頁+商家頁部分
項目總結:vue.js2.5餓了么APP(7)項目部署與總結
項目github鏈接: https://github.com/Rachel-X-4869/cube-ui-eleme-project
