饿了么–vue项目总结
饿了么–vue项目总结
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移动端视图,并且引入重置样式:
-
-
<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”: 指的就是一种网页效果: 如果页面内容不足够长时,页脚固定在浏览器窗口的底部;如果内容足够长时,页脚固定在页面的最底部。但如果网页内容不够长,置底的页脚就会保持在浏览器窗口底部。
参考链接: 各种CSS实现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