項目是基於組件化開發的思想,可以看做是在App.vue這個大組件內編寫以下小組件:包括頭部,中間導航區,以及最底下的內容區,使用vue-router來控制中間導航區(商品,商家,評價)頁面的跳轉。
1.先引入reset.css(文件路徑:項目 -> static -> css)將標簽默認樣式進行設置,除了文件默認設置外,還會自定義一些標簽樣式,以保證后期項目更加美觀的在手機上進行展現。文件下載地址:http://cssreset.com。
reset.css文件中自定義部分:

1 /* custom */ 2 a { 3 color: #7e8c8d; 4 text-decoration: none; 5 -webkit-backface-visibility: hidden; 6 } 7 8 li { 9 list-style: none; 10 } 11 12 ::-webkit-scrollbar { 13 width: 5px; 14 height: 5px; 15 } 16 17 ::-webkit-scrollbar-track-piece { 18 background-color: rgba(0, 0, 0, 0.2); 19 -webkit-border-radius: 6px; 20 } 21 22 ::-webkit-scrollbar-thumb:vertical { 23 height: 5px; 24 background-color: rgba(125, 125, 125, 0.7); 25 -webkit-border-radius: 6px; 26 } 27 28 ::-webkit-scrollbar-thumb:horizontal { 29 width: 5px; 30 background-color: rgba(125, 125, 125, 0.7); 31 -webkit-border-radius: 6px; 32 } 33 34 html, body { 35 width: 100%; 36 } 37 38 body { 39 -webkit-text-size-adjust: none; 40 -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 41 }
PS:css樣式書寫小技巧
像display、position這些會影響布局的樣式寫在前邊
像height、weight這些會觸發reload重繪的不可繼承的樣式寫在中間
像字體、顏色等會觸發reload重繪的可繼承的樣式寫在最后
2.在 index.html 文件中引入 reset.css 文件,並進行理想視口的定義(寬度,初始縮放比,最大/小縮放比,是否允許縮放):
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <link rel="stylesheet" href="static/css/reset.css">
3.eslint.js 文件:
例如:遇到關於分號的錯誤,因為默認 eslint 是默認不要分號的,如果要加分號,需要在 rules 中添加規則,詳細配置規則可以在控制台報錯中顯示的網址進行查看:
'semi': ['error', 'always'], 'indent': 0, 'space-before-function-paren': 0
4.main.js 文件:/* eslint-disable no-new */
js 中 new 一個對象后是需要賦值給某個值,但是 vue 實例化不需要,所以通過這條規則告訴 eslint 跳過對下面一行代碼的規則校驗,這樣才不會報錯。
5.vue模板設置:webstrome主菜單File -> setting -> Editor -> File and Code Templates -> 右側‘添加 -> 填寫Name,Extension,以及代碼區(如下)。

1 <template> 2 3 </template> 4 5 <script> 6 7 </script> 8 9 <style> 10 11 </style>
6.頭部區塊代碼:在 src -> components -> header -> header.vue中添加代碼,並將組件導出;在App.vue文件中引入 header 組件並注冊,然后才可以使用header組件。

1 <template> 2 <div class="header"> 3 I am header 4 </div> 5 </template> 6 7 <script type="text/ecmascript-6"> 8 export default {}; 9 </script> 10 11 <style lang="stylus" rel="stylesheet/stylus"> 12 13 </style>

1 <div id="app"> 2 <v-header></v-header> 3 <div class="tab"> 4 I am tab 5 </div> 6 <div class="content"> 7 I am content 8 </div> 9 </div>

1 // 引用 2 import header from './components/header/header.vue'; 3 // 注冊 4 export default { 5 components: { 6 'v-header': header 7 } 8 };
PS:
1)因為使用的是 stylus 的語法,還需添加 stylus-loader 以及 stylus 組件庫,否則會遇到:Module build failed: Error: Cannot find module 'stylus' 這種報錯信息。安裝語法:npm install stylus-loader --save-dev 以及 npm install stylus --save-dev。
2)在 App.vue 文件中注冊 header 組件時,變量名不能為 header ,因為和 html5 標簽重復。
3)es6語法,注冊組件時可以簡寫,如 header:header ,簡寫為 header。
7.導航區代碼:
1)在 App.vue中添加導航區代碼以及樣式。導航區是水平排列,並且是三等分,可以使用移動端經典的布局:flex 布局。

1 <div class="tab"> 2 <div class="tab-item">商品</div> 3 <div class="tab-item">評論</div> 4 <div class="tab-item">商家</div> 5 </div>

1 #app 2 .tab 3 display flex 4 width 100% 5 height 40px 6 line-height 40px 7 .tab-item 8 flex 1 9 text-align center
PS:
1)記得給 style 標簽加上 lang 屬性及 rel 屬性,否則會因識別不了 stylus 而報錯。
2)只需要寫標准的 css 代碼即可,vue-loader 可以解決 css 兼容性問題。(vue-loader 在 node-modules 文件夾里)
2)安裝 vue-router 組件庫,通過路由實現頁面跳轉。
用 Vue.js + vue-router 創建單頁應用,是非常簡單的。使用 Vue.js ,已經可以通過組合組件來組成應用程序,當要把 vue-router 添加進來時,需要將組件(components)映射到路由(routes),然后告訴 vue-router 在哪里渲染它們。
vue-router官網文檔:https://router.vuejs.org/zh-cn/essentials/getting-started.html
2-1)安裝命令:npm install vue-router --save。
2-2)App.vue 文件中:使用 router-link 組件來進行商品、評價及商家這三個頁面的導航,通過傳入 `to` 屬性指定鏈接,最后通過<router-view>將路由匹配到的組件渲染在內容區。

1 <div id="app"> 2 <v-header></v-header> 3 <div class="tab"> 4 <div class="tab-item"> 5 <!-- 使用 router-link 組件來導航. --> 6 <!-- 通過傳入 `to` 屬性指定鏈接. --> 7 <!-- <router-link> 默認會被渲染成一個 `<a>` 標簽 --> 8 <router-link to="/goods">商品</router-link> 9 </div> 10 <div class="tab-item"> 11 <router-link to="/ratings">評論</router-link> 12 </div> 13 <div class="tab-item"> 14 <router-link to="/seller">商家</router-link> 15 </div> 16 </div> 17 <!--內容區--> 18 <div class="content"> 19 <!-- 路由出口 --> 20 <!-- 路由匹配到的組件將渲染在這里 --> 21 <router-view></router-view> 22 </div> 23 </div>
2-3)goods,ratings,seller 組建的創建
在 components 文件夾中新建文件夾 goods,在 goods 文件夾新建文件 goods.vue,同理完成 ratings 和 seller 組件的創建。
以下是 goods.vue 代碼內容,ratings.vue 和 seller.vue 同理。
2-4)main.js 文件中:
第一步:把 vue-router 的 export 值賦值給變量 VueRouter 。
第二步:如果使用模塊化機制編程,導入Vue和VueRouter,要調用 Vue.use(VueRouter),這樣才能成功安裝路由功能。
第三步:定義(路由)組件。可以從其他文件 import 進來。(這里涉及文件別名設置知識點,具體可以看下面 PS 內容中第五點)
第四步:定義路由。每個路由應該映射一個組件。 其中"component" 可以是通過 Vue.extend() 創建的組件構造器,或者只是一個組件配置對象。
第五步:創建 router 實例,然后傳 `routes` 配置。
第六步:創建和掛載根實例。記得要通過 router 配置參數注入路由,從而讓整個應用都有路由功能。
第七步:使用 router.push 設置打開項目后默認顯示商品頁面。

1 // The Vue build version to load with the `import` command 2 // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 import Vue from 'vue'; 4 import App from './App'; 5 import VueRouter from 'vue-router'; 6 // 1. 定義(路由)組件.可以從其他文件 import 進來 7 import goods from 'components/goods/goods'; 8 import ratings from 'components/ratings/ratings'; 9 import seller from 'components/seller/seller'; 10 11 // 引入自定義的css樣式 12 import 'common/stylus/index.styl'; 13 14 // 0. 如果使用模塊化機制編程,導入Vue和VueRouter,要調用 Vue.use(VueRouter) 15 Vue.use(VueRouter); 16 17 Vue.config.productionTip = false; 18 19 // 2. 定義路由 20 // 每個路由應該映射一個組件。 其中"component" 可以是 21 // 通過 Vue.extend() 創建的組件構造器, 22 // 或者,只是一個組件配置對象。 23 // 我們晚點再討論嵌套路由。 24 const routes = [ 25 {path: '/goods', component: goods}, 26 {path: '/ratings', component: ratings}, 27 {path: '/seller', component: seller} 28 ]; 29 30 // 3. 創建 router 實例,然后傳 `routes` 配置 31 // 你還可以傳別的配置參數, 不過先這么簡單着吧。 32 const router = new VueRouter({ 33 routes, // (縮寫)相當於 routes: routes 34 linkActiveClass: 'active' 35 }); 36 37 // 4. 創建和掛載根實例。 38 // 記得要通過 router 配置參數注入路由, 39 // 從而讓整個應用都有路由功能 40 /* eslint-disable no-new */ 41 new Vue({ 42 el: '#app', 43 template: '<App/>', 44 components: {App}, 45 router 46 }); 47 // 現在,應用已經啟動了! 48 49 // 頁面加載自動導航到goods頁面 50 router.push('/goods');
2-5)樣式設置。
2-5-1)關於 active 的設置
在瀏覽器調試時,當點擊商品、評論或者商家時,可以看到默認添加了一個名為 “router-link-active” 的類,這是vue-router 默認添加的,方便用戶進行高亮等配置。可以直接在代碼中對這個類名進行樣式設置。如果覺得類名太長,可以在 vue-router 實例化進行選項配置,將默認類名改成自己想要的名稱,比如將 “router-link-active” 改為 “active”。
2-5-2)1 像素邊框的設置
問題背景:因為這是一個 webapp 應用,在手機端調試時會發現 1 像素邊框有時候並不精確等於 1 像素,這是和手機的設備像素比(dpr) 有關。
設計思路:先在 .tab 上通過偽類 after,來增加一條下邊框的線(寫在 mixin.styl 文件中),再通過全局定義的 “border-1px” 這個類,根據手機 dpr 的不同對上邊的偽類進行縮放(寫在 base.styl 文件中),從而達到1 像素邊框的設置。如果要設置上邊框,就用偽類 before。
實現步驟:
第一步:在 mixin.styl 文件中完成 “border-1px” 的設置,在App.vue 中通過 @import 引入該文件,然后在 .tab 下使用該類。
第二步:在 base.styl 文件中完成 “border-1px” 的設置,在 index.styl 文件中加載所有樣式文件,在main.js 中通過 @import 引入該文件。(這里涉及文件別名設置知識點,具體可以看下面 PS 內容中第五點)
第三步,在App.vue 中使用全局樣式 “border-1px”。
注意:icol.styl 文件中有一些關於圖標字體原路徑的設置,因為路徑變化,所以運行時可能會出錯找不到文件。遇到這種情況修改一下文件中的路徑就可以了。
關於樣式設置部分具體順序可見下圖。

1 border-1px($color) 2 position relative 3 // 進行偽類設置,一定要設置寬度,因為元素脫離了文檔流 4 &:after 5 display block 6 position absolute 7 left 0 8 bottom 0 9 width 100% 10 border-top 1px solid $color 11 content ' '

1 //為什么要寫 -webkit :因為這里沒有兼容性文件控制,所以要手寫兼容性代碼 2 //本例需要的是1像素的邊框,所以當dpr為1.5時,取0.7倍(1.5*0.7=1.05約等於1)。dpr為2時,取0.5倍(2*0.5=1) 3 @madia (-webkit-min-device-pixel-ratio 1.5) 4 (-min-device-pixel-ratio 1.5) 5 .border-1px 6 &::after 7 -webkit-transform scaleY(0.7) 8 transform scaleY(0.7) 9 10 @madia (-webkit-min-device-pixel-ratio 2) 11 (-min-device-pixel-ratio 2) 12 .border-1px 13 &::after 14 -webkit-transform scaleY(0.5) 15 transform scaleY(0.5)

1 <template> 2 <div id="app"> 3 <v-header></v-header> 4 <div class="tab border-1px"> 5 <div class="tab-item"> 6 <!-- 使用 router-link 組件來導航. --> 7 <!-- 通過傳入 `to` 屬性指定鏈接. --> 8 <!-- <router-link> 默認會被渲染成一個 `<a>` 標簽 --> 9 <router-link to="/goods">商品</router-link> 10 </div> 11 <div class="tab-item"> 12 <router-link to="/ratings">評論</router-link> 13 </div> 14 <div class="tab-item"> 15 <router-link to="/seller">商家</router-link> 16 </div> 17 </div> 18 <!--內容區--> 19 <div class="content"> 20 <!-- 路由出口 --> 21 <!-- 路由匹配到的組件將渲染在這里 --> 22 <router-view></router-view> 23 </div> 24 </div> 25 26 27 </template> 28 29 <script> 30 // 引用 31 import header from 'components/header/header.vue'; 32 // 注冊 33 export default { 34 components: { 35 'v-header': header 36 } 37 }; 38 </script> 39 40 <style lang="stylus" rel="stylesheet/stylus"> 41 @import "common/stylus/mixin.styl" 42 #app 43 .tab 44 display flex 45 width 100% 46 height 40px 47 line-height 40px 48 border-1px(rgba(7, 17, 27, 0.1)) 49 .tab-item 50 flex 1 51 text-align center 52 /* &:表示父元素,即.tab-item */ 53 & > a 54 /* 區塊點擊才能有反應 */ 55 display block 56 font-size 14px 57 color rgb(77, 85, 93) 58 &.active 59 color rgb(240, 20, 20) 60 </style>

1 // The Vue build version to load with the `import` command 2 // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 import Vue from 'vue'; 4 import App from './App'; 5 import VueRouter from 'vue-router'; 6 // 1. 定義(路由)組件.可以從其他文件 import 進來 7 import goods from 'components/goods/goods'; 8 import ratings from 'components/ratings/ratings'; 9 import seller from 'components/seller/seller'; 10 11 // 引入自定義的css樣式 12 import 'common/stylus/index.styl'; 13 14 // 0. 如果使用模塊化機制編程,導入Vue和VueRouter,要調用 Vue.use(VueRouter) 15 Vue.use(VueRouter); 16 17 Vue.config.productionTip = false; 18 19 // 2. 定義路由 20 // 每個路由應該映射一個組件。 其中"component" 可以是 21 // 通過 Vue.extend() 創建的組件構造器, 22 // 或者,只是一個組件配置對象。 23 // 我們晚點再討論嵌套路由。 24 const routes = [ 25 {path: '/goods', component: goods}, 26 {path: '/ratings', component: ratings}, 27 {path: '/seller', component: seller} 28 ]; 29 30 // 3. 創建 router 實例,然后傳 `routes` 配置 31 // 你還可以傳別的配置參數, 不過先這么簡單着吧。 32 const router = new VueRouter({ 33 routes, // (縮寫)相當於 routes: routes 34 linkActiveClass: 'active' 35 }); 36 37 // 4. 創建和掛載根實例。 38 // 記得要通過 router 配置參數注入路由, 39 // 從而讓整個應用都有路由功能 40 /* eslint-disable no-new */ 41 new Vue({ 42 el: '#app', 43 template: '<App/>', 44 components: {App}, 45 router 46 }); 47 // 現在,應用已經啟動了! 48 49 // 頁面加載自動導航到goods頁面 50 router.push('/goods');
PS:
1)import VueRouter from 'vue-router' 中,為什么是 vue-router 而不是其他值?
這是根據 node modules -> vue-router ->package.json 文件中 name 的值決定的。
2)關於router-go的改變:https://cn.vuejs.org/v2/guide/migration-vue-router.html#router-go-%E6%94%B9%E5%8F%98 。
3)關於 v-link-active 的替換:https://cn.vuejs.org/v2/guide/migration-vue-router.html#v-link-active-替換。
4)關於 linkActiveClass 的設置:https://router.vuejs.org/zh-cn/api/options.html#linkactiveclass
5)文件別名的設置:在 webpack.base.conf.js 文件中,module.exports -》resolve 下增加代碼 'components': '../src/components' ,之后在任何文件中導入 components 文件夾中的文件時,都可以直接寫 ‘components/......’,不需要寫 ‘../../../components’,就是不需要理會文件所處的相對路徑,這在編輯器沒有提示功能的時候有很大的用處,不容易出錯。配置完需要退出,重新啟動下程序,配置才能生效。
6)設備像素比相關知識:http://www.zhangxinxu.com/wordpress/2012/08/window-devicepixelratio/
7)css預處理器(待整理)
8)關於文件:mixin.styl 是一些單獨的樣式設置;base.styl 是全局的樣式設置;index.styl 是將一些需要引用的樣式文件加載進來,然后在 main.js 中全局引入樣式文件即可,這樣代碼比較簡潔,也不容易出錯。
9)關於手機端調試
法一(嘗試過沒有成功):命令行運行 ipconfig ,找出 ip(假設是192.168.1.111),在手機瀏覽器頁面輸入http://192.168.1.111:8080/#/goods 即可看到效果。但是我自己調試過沒辦法,感興趣的朋友可以試一下。
法二(成功):在 webpack.dev.conf.js 文件中,找到 devServer 下的 host 的配置進行修改。假設本機 ip 地址是192.168.1.111,則將配置改成 host: '192.168.1.111',保存好后重新跑一下項目就可以了。注意:手機端和電腦必須在同一局域網內,簡單地說就是連接同一個 wifi,否則手機端無法看到效果。
10)關於草料二維碼:可以復制上述網址 http://192.168.1.111:8080/#/goods 到 草料二維碼生成器 生成二維碼,然后用手機掃碼方式就可直接進入頁面,無需手動輸入網址,便捷高效。
8.內容區代碼:在 App.vue中添加導航區代碼以及樣式。導航區是水平排列,並且是三等分,可以使用移動端經典的布局:flex 布局。
具體內容后續補充。