外卖项目从0到1

224 阅读4分钟

第一章:准备

1.1 项目介绍

  • 此项目为外卖web App(SAP)
  • 包括商家,商品,购物车,用户等子模块
  • 使用vue全家桶+ES6+webpack前端热门技术
  • 采用模块化、组件化、工程化的模式开发

1.2 技术选型

1.3 前台路由

1.4 API接口

  • 全称:前后端交互API接口
  • mock数据:模拟数据,当后端没有写好的时候,提前mock数据

1.5 技术成长

  • 可以学习项目开发流程

      熟悉一个项目开发流程
      学会组件化、模块化、工程化的开发模式
      通脚手架创建初始化项目
      学会模拟json后端数据,实现前后端分离开发
      学会ES6+eslink的开发方式
      掌握项目开发技巧
    
  • 插件和第三方库

      学会使用vue-router开发单页面应用
      学会axios、vue-resource与后端的数据进行交互
      学会vuex管理应用组件状态
      学会使用better-scroll、vue-scroller实现页面滑动效果
      学会mint-ui组件库构建页面
      学会使用vue-lazy实现图片懒加载
      学会使用mockjs模拟后台接口数据
    
  • 样式、布局、效果相关

       stylus编写模块化的css
       学会使用Vue.js的过度编写炫酷的交互动画
       学会制作并使用图标字体
       学会解决移动端1px边框问题
       学会移动端经典的css sticky  footer布局
       学会flex弹性布局
    

第二章 应用开发

2.1开启项目开发

  • 2.1.1 使用vue-cli(脚手架)搭建项目

    vue-cli是官方提供的用于搭建基于vue+webpack+es6项目的脚手架工具

    操作步骤:

     npm install -g vue-cli
     vue init webpack gshop
     cd gshop
     npm install
     npm run dev
    
  • 2.1.2 编码测试与打包发布项目 开发环境运行 npm run dev 在内存中对我们的项目进行编译打包,运行起来,

2.2 资源准备

  • 标注图
  • 切图
  • 图片Base64,把图片转换成字符串,好处:这样
  • 2x和3x图
  • iconfig

2.3 项目的目录结构

2.4 stylus

2.4.1 当前主流三种css预编译器

  • 1) Less
  • 2) Sass
  • 3)Stylus

2.4.2 安装stylus依赖包

两个包,webpack本身只能理解js以外,css有css-loader、stylus-loader是将stylus转换成css,让webpack理解stylus,

 npm install stylus stylus-loader --save-dev

2.4.3 编写样式

<style lang="stylus" rel="stylesheet/stylus">
 </style>

2.4.4 引入reset样式

1)static/css/reset.css

/**
 * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
 * http://cssreset.com
 */
 html, body, div, span, applet, object, iframe,
 h1, h2, h3, h4, h5, h6, p, blockquote, pre,
 a, abbr, acronym, address, big, cite, code,
 del, dfn, em, img, ins, kbd, q, s, samp,
 small, strike, strong, sub, sup, tt, var,
 b, u, i, center,
 dl, dt, dd, ol, ul, li,
 fieldset, form, label, legend,
 table, caption, tbody, tfoot, thead, tr, th, td,
 article, aside, canvas, details, embed,
 figure, figcaption, footer, header,
 menu, nav, output, ruby, section, summary,
 time, mark, audio, video, input {
   margin: 0;
   padding: 0;
   border: 0;
   font-size: 100%;
   font-weight: normal;
   vertical-align: baseline;
 }
 
 /* HTML5 display-role reset for older browsers */
 article, aside, details, figcaption, figure,
 footer, header, menu, nav, section {
   display: block;
 }
 
 body {
   line-height: 1;
 }
 
 blockquote, q {
   quotes: none;
 }
 
 blockquote:before, blockquote:after,
 q:before, q:after {
   content: none;
 }
 
 table {
   border-collapse: collapse;
   border-spacing: 0;
 }
 
 /* custom */
 a {
   color: #7e8c8d;
   text-decoration: none;
   -webkit-backface-visibility: hidden;
 }
 
 li {
   list-style: none;
 }
 
 ::-webkit-scrollbar {
   width: 5px;
   height: 5px;
 }
 
 ::-webkit-scrollbar-track-piece {
   background-color: rgba(0, 0, 0, 0.2);
   -webkit-border-radius: 6px;
 }
 
 ::-webkit-scrollbar-thumb:vertical {
   height: 5px;
   background-color: rgba(125, 125, 125, 0.7);
   -webkit-border-radius: 6px;
 }
 
 ::-webkit-scrollbar-thumb:horizontal {
   width: 5px;
   background-color: rgba(125, 125, 125, 0.7);
   -webkit-border-radius: 6px;
 }
 
 html, body {
   width: 100%;
   height: 100%;
 }
 
 body {
   -webkit-text-size-adjust: none;
   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
 }
 
 /*显示省略号*/
 .ellipsis{
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
 }

2.4.5移动端

1)viewport

<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">

2)解决点击延时0.3s问题

300 毫秒 因为浏览器捕获第一次单击后,会先等待一段时间,如果在这段时间区间里用户未进行下一次点击,则浏览器会做单击事件的处理。如果这段时间里用户进行了第二次单击操作,则浏览器会做双击事件处理。 推荐 fastclick.js

<script>
  if ('addEventListener' in document) {
    document.addEventListener('DOMContentLoaded', function () {
      FastClick.attach(document.body);
    }, false);
  }
  if (!window.Promise) {
    document.writeln('<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js"' + '>' + '<' + '/' + 'script>');
  }
</script>

2.5 引入vue-router

  • 2.5.1 下载路由 npm install vue-router --save
  • 2.5.1 定义路由器
// 路由器对象模块
import Vue from 'vue'
import VueRouter from 'vue-router'
import MSite from '../pages/MSite/Msite.vue'
import Order from '../pages/Order/Order.vue'
import Profile from '../pages/Profile/Profile.vue'
import Search from '../pages/Search/Search.vue'

// 声明使用插件
Vue.use(VueRouter)

export default new VueRouter({
 // 配置所有多有routes数组
 routes: [
   // 路由是个对象
   {
     path: '/msite',
     component: MSite
   },
   {
     path: '/order',
     component: Order
   },
   {
     path: '/profile',
     component: Profile
   },
   {
     path: '/search',
     component: Search
   },
   // 默认显示msite
   {
     path:'/',
     redirect:'/msite'
   }
 ]
})
  • 2.5.3 注入路由器 main入口js里面映射上路由,先引入路由器,然后配置路由器,配置上router产生两方面结果: 第一:多了几个组件标签router-link、keep-alive、router-view 第二:多了两个属性可以访问 routeroute、router

1、注入路由器,我们可以在任何组件内通过 this.$router 访问路由器

2、也可以通过 this.$route 访问当前路由

// 入口JS
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  render:h=>h(App),
  router
})

2.6 FooterGuide组件

2.6.1 说明

  • 1)通过编程式导航实现路由的切换显示($router)
  • 2)通过动态的class和$route.path来实现tab样式切换
  • 3)通过阿里图标库,显示导航图标
<template>
   <div class="footer_guide">
        <a href="javascript:;" class="guide_item on">
            <span class="item_icon"> 
                <i class="iconfont icon-waimai"></i>
            </span>
            <span>
                外卖
            </span>
        </a>
         <a href="javascript:;" class="guide_item">
            <span class="item_icon"> 
                <i class="iconfont icon-search"></i>
            </span>
            <span>
                搜索
            </span>
        </a>
         <a href="javascript:;" class="guide_item">
            <span class="item_icon"> 
                <i class="iconfont icon-order"></i>
            </span>
            <span>
                订单
            </span>
        </a>
         <a href="javascript:;" class="guide_item">
            <span class="item_icon"> 
                <i class="iconfont icon-wode"></i>
            </span>
            <span>
                我的
            </span>
        </a>
   </div>
</template>
<script>
export default {
   
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixins.styl"
.footer_guide
  top-border-1px(#e4e4e4) 
  position fixed
  z-index 100
  left 0
  bottom 0
  right 0
  display flex
  width 100%
  height 50px
  background-color #fff
  .guide_item
    display flex
    flex 1
    flex-direction  column
    align-items center
    margin 5px
    color #999999
    &.on 
      color #02a774
    span 
      font-size 12px
      margin-top 2px
      margin-botton 2px
      .iconfont
        font-size 22px
</style>

优化:利用对象语法写类名,类名确定,但是有没有这个类不确定,非常适合使用对象语法去写class :class="{on: '/msite'===$route.path}当当前的路径跟对应的tab相等时样式on有效 goTo('/msite')点击tab的时候切换路由

<a href="javascript:;" class="guide_item" :class="{on: '/msite'===$route.path}" @click="goTo('/msite')">
     <span class="item_icon"> 
       <i class="iconfont icon-waimai"></i>
     </span>
     <span>
        外卖
     </span>
 </a>
goTo(path){
  this.$router.replace(path)
}