饿了么--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”:  指的就是一种网页效果: 如果页面内容不足够长时,页脚固定在浏览器窗口的底部;如果内容足够长时,页脚固定在页面的最底部。但如果网页内容不够长,置底的页脚就会保持在浏览器窗口底部。

参考链接: 各种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





猜你喜欢

转载自blog.csdn.net/weixin_41892205/article/details/80959182