餓了麼--vue專案總結
來遲了來遲了,早就應該動手寫了,無奈卡在webpack的學習中,深陷泥潭。
github原始碼地址:餓了麼專案原始碼
餓了麼專案包含以下三個方面的技術點,以及所瞭解的知識。
1. 流程及開發方法:
- 元件化、模組化的開發模式
- 學會模擬json後端資料,前後端分離開發
- 瞭解webpack的打包原理
2. 第三方元件
- 學會使用vue-router開發單頁應用
- 學會使用vue-resource與後端資料互動
- 學會如何在Vue.js框架裡和第三方JS外掛互動
3. 設計思想與模式
- 瞭解移動端裝置畫素比的概念
- 學會解決移動端1px邊框問題
- 學會移動端經典的css sticky footer佈局
- 學會flex彈性佈局
第一個方面從webpack設定入手:
在build/webpack.base.conf.js檔案下,可以看到基本的webpack設定(出入口檔案位置,字尾補充以及別名等):
module.exports = { context: path.resolve(__dirname, '../'), // webpack編譯的入口檔案 entry: { app: './src/main.js' }, output: { path: config.build.assetsRoot, // 生成的檔名字 filename: '[name].js', // 請求的靜態資源的絕對路徑 publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, resolve: { // 自動補全檔案字尾 extensions: ['.js', '.vue', '.json'], // 別名,只針對於js庫,css的引入還是要寫相對路徑,不能省略 alias: { '@': resolve('src'), // vue:'vue/dist/vue.js', 'components': path.resolve(__dirname, '../src/components'), 'common': path.resolve(__dirname, '../src/common'), //當在js檔案中import其他檔案時路徑直接寫commont相當於../src/common } },
然後在webpack.dev.conf.js檔案中,設定了資料所在的位置,用於模擬後端資料的獲取。
// 資料獲取 var express = require('express') // express 是nodejs框架 var apiServer = express() var bodyParser = require('body-parser') apiServer.use(bodyParser.urlencoded({ extended: true })) apiServer.use(bodyParser.json()) var apiRouter = express.Router() var fs = require('fs') apiRouter.route('/:apiName') //介面路徑 .all(function (req, res) { fs.readFile('./db.json', 'utf8', function (err, data) { //讀取介面檔案 if (err) throw err var data = JSON.parse(data) if (data[req.params.apiName]) { res.json(data[req.params.apiName]) } else { res.send('no such api name') } }) }) // 資料所在的位置 apiServer.use('/api', apiRouter); apiServer.listen(3000, function (err) { if (err) { console.log(err) return } console.log('Listening at http://localhost:' + 3000 + '\n') })
之後config/index.js目錄下
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static', //被webpack編譯處理過的資原始檔都會在這個目錄下
assetsPublicPath: '/', //根目錄
proxyTable: { //解決跨域問題
'/api': 'http://localhost:3000/'
},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false,
devtool: 'cheap-module-eval-source-map', //編譯輸出格式
},
}
webpack打包原理:
現象:假如說需要引入一大堆的js/css檔案,且相互之間還存在引用關係,手動處理的時候就得按照一定的順序。
解決:webpack將一大堆的檔案都從一個入口引入,然後自動處理。(將模組的前後關係打包成一個js,指定js的單獨打包等等),webpack實現模組化的管理。
功能:
1、根據模板生成html,並且自動處理上面的css/JS引用路徑
2、自動處理img裡圖片路徑,css樣式中背景圖的路徑...字型引用
3、開啟本地伺服器,變寫程式碼邊自動更新頁面內容
4、編譯jsx、es6、sass、less、coffeescript等等並新增md5、sourcemap等輔助
5、非同步載入內容,比如彈出框,不需要時不載入到dom
6、配合vue.js、react等框架開發等。
第二方面vue的主要檔案設定:
根目錄下的index.html設定viewport移動端檢視,並且引入重置樣式:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vueeleme</title>
<meta name="viewport" content="width=device-width,inital-scale=1.0,
maximum-scale=1.0,user-scalable=no"> // 這個meta標籤使得頁面寬度等於裝置寬度,頁面的縮放預設為1,且使用者不能縮放。
<link rel="stylesheet" href="./static/css/reset.css"> //基礎樣式重置
</head>
<body>
<div id="app"></div> //掛載所需的id(在main.js中設定)
<!-- built files will be auto injected -->
</body>
</html>
main.js: 匯入VueRouter 管理路由, 匯入 VueResource實現資料互動。
///////main.js檔案部分內容:
const routes = [ //設定路由及相應元件
{
path:'/',
redirect:"goods" //根目錄下重定向到主頁面
},
{
path:'/goods', //不同的路由使用不同的元件
component:goods
},
{
path:'/ratings',
component:ratings
},{
path:'/seller',
component:seller
}
]
const router = new VueRouter({ //將路由匯入VueRouter
mode:'history', //可以去掉#
'linkActiveClass': 'active',
routes
})
const app = new Vue({ //渲染App.vue, 掛載到idnex.html中的#app中
router,
render: h => h(App)
}).$mount('#app')
App.vue 頭部採用元件的形式,導航採用flex佈局三等分,內容利用路由router-view進行顯示。
<template>
<div>
<!-- 頭部 -->
<v-header :seller="seller"></v-header> //元件化
<!-- 中部導航欄 -->
<div class="tab border-1px"> //flex三等分佈局
<div class="tab-item">
<router-link to="/goods">商品</router-link>
</div>
<div class="tab-item">
<router-link to="/ratings">評論</router-link>
</div>
<div class="tab-item">
<router-link to="/seller">商家</router-link>
</div>
</div>
<!-- 路由改變時,顯示相應的內容 -->
<keep-alive>
<router-view :seller="seller"></router-view> //父元件傳遞資料
</keep-alive>
</div>
</template>
第三方面設計思路:
裝置畫素比:devicePixelRatio,視覺稿是以iphone6的375×667螢幕螢幕高度作為基準,為了達到高清效果,視覺稿的畫布大小會是基準的2倍。(對iphone6而言:原先的375×667,就會變成750×1334)。而在設計時候的數值為設計稿上的一半。
並且需要知道:1px 的 CSS 畫素並不一定等於 1px 的物理畫素,不同的裝置會根據其對應裝置畫素比決定使用多少個物理畫素顯示 1px 的 CSS 畫素。所以,在移動端不建議使用 px 作為佈局單位,而是應該使用 rem 或者百分比作為佈局單位。
移動端1px邊框: 利用偽類元素設定邊框
border-1px($color)
position : relative
&:after
display: block
position: absolute
left: 0
bottom: 0
border-top 1px solid $color
width: 100%
content: ''
“Sticky Footer”: 指的就是一種網頁效果: 如果頁面內容不足夠長時,頁尾固定在瀏覽器視窗的底部;如果內容足夠長時,頁尾固定在頁面的最底部。但如果網頁內容不夠長,置底的頁尾就會保持在瀏覽器視窗底部。
自適應佈局:flex,兩端的line自適應
html:
<div class="title">
<div class="line"></div>
<div class="text">優惠訊息</div>
<div class="line"></div>
</div>
CSS:
.title
display: flex
margin: 28px auto 24px auto
width:80%
.line
flex:1
position:relative
top: -6px
border-bottom:1px solid rgba(255,255,255,.2)
.text
padding:0 12px
font-size:14px
font-weight:700