原文https://www.cnblogs.com/ljq66/p/9980372.html

前言:学习Vue.js高仿饿了么课程过程中,总结了这个Web App项目从准备到开发完毕自己觉得很重要的知识点。这一篇主要介绍:项目准备、页面骨架开发、header组件开发。

项目github地址:https://github.com/66Web/ljq_eleme,欢迎Star。


App header
一、项目分析&学习目标

当前最火的MVVM框架

  • Vue.js —— 轻量、简洁、高效、数据驱动、组件化

高仿上线外卖App标准来开发

  • 核心模块 —— 商家模块

开发一个webApp的全流程

  1. 需求分析
  2. 脚手架工具
  3. 数据mock
  4. 架构设计
  5. 代码编写
  6. 自测
  7. 编译打包

以线上生产环境的代码质量作标准

  • 代码开发及测试环节:
  1. UI标注
  2. 真实数据演示
  • 代码规范
  1. 架构设计
  2. 组件抽象
  3. 模块拆分
  4. 代码风格统一
  5. JS变量命名规范
  6. CSS代码规范

功能技术分析

  • vue-resource:  和后端做数据交互
  • vue-router:  做前端路由,实现单页应用
  • 第三方JS库better-scroll:  列表滚动的实现
  • 最大程度组件化: 提高代码的复用
  • html5的localstorage:【收藏商家】功能—存储在浏览器端
  • 细节:图标字体的使用
  • 移动端1像素边框
  • css sticky footer布局
  • flex 弹性布局

      学习目标

  • 掌握Vue.js在实战中的运用
  • 学会使用Vue.js【完整的】开发移动端App
  • 学会组件化、模块化的开发

学习内容

  • Vue.js框架介绍
  • Vue-cli 脚手架 —— 搭建基本代码框架
  • vue-router 官方插件 —— 管理路由
  • vue-resource 官方插件 —— 和后端作Ajax通信
  • Webpack 开源构建工具(把源代码经过编译生成浏览器可以识别和运行的代码)
  • es6 + eslint eslint —— es6代码风格检查工具
  • 工程化 组件化 模块化
  • 移动端常用开发技巧:
  1. flex弹性布局
  2. css stickyfooter
  3. 酷炫的交互设计
二、Vue.js介绍

近年来前端开发趋势

  • 旧浏览器逐渐淘汰,移动端需求增加
  • 前端交互越来越多,功能越来越复杂
  • 架构从传统后台MVC 向REST API+ 前端MV* 迁移

(前者传统MVC:更新数据会刷新页面 后者前端MV*: 向后端REST API异步请求数据,局部刷新页面)

MV* —— MVC、MVP、MVVM

MVVM框架

View    ViewModel    Model

视图        通讯           数据

  • DOM 观察者 Javascript对象
  1. 针对具有复杂交互逻辑的前端应用
  2. 提供基础的架构抽象
  3. 通过Ajax数据持久化,保证前端用户体验
  • MVVM框架技术:vue.js、react.js、Angular.js

      对比Anglar  React

  • Vue.js更轻量,gzip后大小只有 20K+
  • Vuejs更易上手,学习曲线平稳
  • 吸收两家之长,借鉴了angular的指令和react的组件化

vue.js 核心思想

  • 数据驱动
  • 组件化

      组件设计原则

  • 页面上每个独立的可视/可交互区域视为一个组件
  • 每个组件对应一个工程目录,组件所需要的各种资源在这个目录下【就近维护】
  • 页面不过是组件的容器,组件可以嵌套自由组合形成完整的页面
三、Vue-cli开启Vue项目

   Vue-cli 是Vue的脚手架工具 —— 帮助写好Vue基础代码的工具

  1. 目录结构
  2. 本地调试
  3. 代码部署
  4. 热加载
  5. 单元测试

安装使用

1

(sudo) npm install -g vue-cli  // sudo:mac环境下有关管理权限的命令

1

vue init webpack my-project

项目文件

  • src文件夹:存放项目源码
  • bulld目录+ config目录:webpack配置相关
  • node_modules文件夹:npm install 安装的依赖代码库
  1. static—>.gitkeep: 当这个目录为空时也可以将它提交到git仓库中
  2. babelrc : babel的一些配置,es6语法的转换
  3. .editorconfig: 编辑器的配置
  4. .eslintignore: 忽略语法检查的目录文件,一般忽略build目录和node_modules目录
  5. .eslintrc.js: eslint的配置文件
  6. gitignore: 上传git仓库要忽略的一些文件的配置
  7. index.html: 入口html文件,要使用的css和js文件会在编译过程中自动插入
  8. package.json:整个项目的配置文件,一般用来描述项目 ↓

→  scripts:  配置一些需要执行的命令
        →  dependencies:开发环境中的依赖
        →  devdependencies: 编译过程中的依赖

项目运行

1

npm run dev 

  • src开发目录下:
  1. main.js —— 项目入口文件
  2. App.vue —— 主页面组件
  • vue语法糖:  export default { } 一个对象——可以定义一个组件
【小知识点】sublime自动格式化 —— Command+option+L 或 Control+alt+L
  • 在父组件中使用子组件,如Hello.vue:
  1. 引用

    import Hello from './compoments/Hello'
  2. 注册
    export default{components: {Hello   //es6语法  相当于 'Hello': Hello}
    }
  3. 使用标签
    <hello><hello>

开发时的Webpack配置与编译

  • build->dev-server.js 或 Webpack.dev.conf.js
  • webpack.base.conf.js : 配置各种文件的Loader

→  配置默认识别的路径

resolve: {extensions: ['.js', '.vue', '.json'],alias: {'vue$': 'vue/dist/vue.esm.js','@': resolve('src'),}
}

四、准备工作

图标字体制作 

  • 在线制作网站:https://icomoon.io/app/#/select
  • 将自己的SVG图标导入,输出自己的图标字体文件
  • Import Icons → Generate Fonts → preferences修改名称 → Download
  • 使用:icon.css和fonts文件夹下所有文件

项目目录设计

  • src->common目录下:项目公用文件 js、style、fonts

【css的stylus语法】

  • 删掉分号和大括号, &表示父元素,冒号也可以省略
  • 文件后缀为styl,style中添加lang="stylus"
  • 需要安装:

1

npm install stylus stylus-loader --save-dev

  • resource目录下:项目图片文件——可以删掉无用的assets目录,但需要修改引用到的地方
  • components目录下:布局、业务功能等分模块管理组件,如header目录,footer目录
  • static->css目录下:reset.css 标签默认样式
  • 在  index.html 中引入:
<link rel="stylesheet" type="text/css" href="static/css/reset.css">

前后端分离

  • Vue SPA —— 前端通过 vue-resource  Ajax从后端获取数据
  • 前端最重要的任务:mock数据(后台数据模拟) data.json
{"seller":{} //商家相关字段"goods":{} //商品相关字段"rattings":{} //评论相关字段
} 

 webpack.dev.conf.js中配置

  • 使用 express框架  开启一个node server,用 express.Router 编写这些接口请求
  1. 首先:在 const portfinder = require(‘portfinder’) 后添加

    const express = require('express')//开启一个node server
    const app = express() //定义一个对象,包含express返回的数据var appData = require('../data.json') //定义一个对象引入data数据
    var seller = appData.seller;
    var goods = appData.goods;
    var ratings = appData.ratings;app.use('/api', apiRoutes); //调用app对象

  2. 然后:找到 devserver{}, 在里面添加

    before(app) {app.get('/api/seller', (req, res) => {res.json({errno: 0, //错误码:实际上是业务方根据业务自己定的data: seller}) //接口返回json数据,上面配置的数据seller就赋值给data请求后调用}),app.get('/api/goods', (req, res) => {res.json({errno: 0,data: goods})}),app.get('/api/ratings', (req, res) => {res.json({errno: 0,data: ratings})})
    }

  • 注意:每次配置完 express 之后都需要重新启动

查看json数据

  • 在Google地址栏中输入:localhost:8080/api/seller
  • 依赖Google的jsonview插件 —— 安装 使数据格式化

【Google安装第三方插件】

  • 打开https://github.com ;
  • 搜索 jsonView 链接:https://github.com/search?utf8=%E2%9C%93&q=jsonview;
  • 选择需要的插件(我下载的是这个gildas-lormeau/JSONView-for-Chrome);
  • 点击【Download Zip】,插件下载完成,解压缩到相应目录(D:\Download\JSONView-for-Chrome-master);
  • 安装,打开chrome - 扩展程序 (地址栏输入chrome://extensions/);
  • 右上角,选中开发模式;
  • 点击”加载正在开发的扩展程序…”
  • 选择插件目录(D:\Download\JSONView-for-Chrome-master\WebContent);
  • 安装完成,重新加载 (Ctrl+R)。
  • 测试地址:http://jsonview.com/example.json

—— 转载自【小白白打酱油博客】

五、页面骨架开发

移动端视口

  • index.html   中通过meta设置视口可被缩放,初试宽高设置
<meta name="viewport"
content="width=device-width,initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">

App.vue 中把页面拆为三个区块

<div id="app"><div class="header">header</div><div class="tab">tab</div><div class="content">content</div>
</div>

然后,分别抽成一个组件,引用 —— 所有组件自定义标签名不可与html本身标签重合 'v-header': header

移动端经典布局  flex 

<div class="tab"><div class="tab-item">商品</div><div class="tab-item">评论</div><div class="tab-item">商家</div>
</div>

.tabdisplay: flexwidth: 100%height: 40pxline-height: 40px.tab-itemflex:1text-align: center

vueRouter

  1. Vue2.0 使用 <router-link> 进行【导航】

    <router-link :to="{ path: '/goods' }">商品</router-link>
  2. 【路由外链 】<router-view> —— 单页面切换的内容页,替换content div区块
    <router-view></router-view>
  3. main.js 中设置单页面应用路由的【挂载组件】—— 默认App.vue 也可以自定义组件如layout.vue

    /* eslint-disable no-new */
    new Vue({el: '#app',router,components: { App },template: '<App/>'
    })

  4. 配置【路由map】:router->index.js

    export default new Router({mode: 'history',routes: [{path: '/',redirect: '/goods',//默认页面重定向},{path: '/goods',component: goods},{path: '/ratings',component: ratings},]
    })

  5. 【点击】高亮显示   a.router-link-active 

    #app .tab .tab-item>a{display: block;font-size: 14px;color: rgb(77, 85, 93);
    }#app .tab .tab-item>a.router-link-active{color: rgb(240, 20, 20)
    }

1像素border实现 

  • 错误做法:直接给tab加1像素边框  X

    .tab{border-bottom: 1px solid rgba(7,17,27,0.1)
    }
  • 问题是:这段代码在PC端显示,是1像素,但是在手机端显示,就不是1像素。
  • 因为手机端有一个DPR的概念:它的物理像素是设备像素的两倍。所以iPhone6上面可能就是一个2像素的边框

【PC开发中用手机实时预览的小技巧】

  • 新开一个gitbash,mac环境下输入命令:ifconfig, windows下输入:ipconfig
  • 获知本机IP地址192.168.1.1,替换掉localhost(表示本机)
  • 将地址http://192.168.1.1:8080/goods#/输入到草料二维码网站中,生成二维码,用手机扫描,即可查看
  • 必须与PC使用的是同一局域网
  • 正确做法:给 tab 加一个伪类:after , 让它是一条1像素的线,然后在DBR为2或3的手机端缩放  √

    <div class="tab border-1px">
  1. 定义mixin.styl:  通过css预处理器的函数方法,实现伪类线

    border-1px($color)position: relative&:beforedisplay: blockposition: absoluteleft:0top: 0width: 100%border-bottom: 1px solid $colorcontent: ''&:afterdisplay: blockposition: absoluteleft:0bottom: 0width: 100%border-top: 1px solid $colorcontent: ''

  2. 定义base.styl: 实现不同DBR的移动端的缩放

    @media(-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)//DPR为1.5的缩放0.7倍
    .border-1px&:before-webkit-transform: scaleY(0.7)transform:scaleY(0.7)&:after-webkit-transform: scaleY(0.7)transform:scaleY(0.7)@media(-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2)//DPR为2的缩放0.5倍
    .border-1px&:before-webkit-transform: scaleY(0.5)transform:scaleY(0.5)&:after-webkit-transform: scaleY(0.5)transform:scaleY(0.5)

  3. 定义index.styl: 引用所有styl文件,最后在 main.js 中全局引用
    @import"./mixin"   //import后无空格
    @import"./icon"
    @import"./base"
    main.js: import '@/common/stylus/index.styl'   //import后有空格
六、header组件开发

vue-resource

  1. 安装 vue-resource

    1

    npm install vue-resource --save

    注意:每次install完插件等之后需要重新启动项目

  2. main.js 文件中:
    import VueResource from 'vue-resource'
    Vue.use(VueResource)

    之后就可以在项目任何地方:使用 this.$http 命令

  3. App.vue 组件中:
  • export module{} 外:

    const ERR_OK = 0;  //定义常量,增强程序可读性
  • export module{} 内:
    data() {return {seller:{}  //维护数据 seller}
    }
  • 异步请求数据,返回的是Promise对象

    created: function () {this.$http.get('/api/seller')    //发送get请求, .then(function(res){              //.then方法 请求完成后调用//第一个函数是请求成功后方法}, function (err) {                //第二个函数是请求失败后方法})
    }

    使用ES6 箭头函数:箭头函数前后必须有空格

    created: function () {this.$http.get('/api/seller').then((res) => { res = res.body //拿到response返回的promise对象的body(Data Object)if (res.errno === ERR_OK) {this.seller = res.data;//console.log(this.seller)} }, (err) => { })
    }

外部组件

  • 父组件  App.vue 中 <header> 组件标签中用v-bind绑定seller属性,传给子组件seller数据

    <v-header :seller="seller"></v-header>
  • 子组件 header.vue 中通过 props属性 获取父组件传来的seller数据

    props: {seller: {type: Object}
    }
  • 模板对应位置 显示 对应seller.xxx 子数据
  1. <img>标签: 使用seller数据图片地址,v-bind绑定src属性

     :src="seller.avatar"
  2. 文本内容: 双向数据绑定显示seller数据
    {{seller.name}}
  3. 如果要获取的是 seller数据对象的  子对象数组的  某一项:因为异步获取数据,子对象可能为undefined,需要先 v-if 判断是否存在
    <div class="support" v-if="seller.supports"><span class="icon" :class="this.classMap[seller.supports[0].type]"></span><span class="text">{{seller.supports[0].description}}</span>
    </div>
  4. 定义 classMap数组,通过获取seller数据中的索引值,应用对应索引的class
    created (){this.classMap = ['decrease','descount','guarantee','invoice','special']
    }
    <span class="icon" :class="this.classMap[seller.supports[0].type]"></span>
  5. mixin.styl 文件中伪函数:实现图片在不同DPR下引用不同的图片路径
    bg-image($url)background-image: url($url+"@2x.png")@media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3)background-image: url($url+"@3x.png")
  • 公告内容 —— 文字【省略号效果】

    white-space: nowrap
    overflow: hidden
    text-overflow: ellipsis
  • 背景图片【模糊滤镜效果】

    .backgroundposition: absolutetop: 0left: 0width: 100%height: 100%z-index: -1filter: blur(10px)   

详情弹层页

  • 实现弹出层
  1. v-show指令 ——  控制弹出层的显示/隐藏

    <div class="detail" v-show="detailShow"></div>
    data () {return {detailShow: false  //通过改变数据detailShow 的true/false,控制元素的显示/隐藏}
    }
  2. @click —— 触发点击事件,执行显示函数
    <div class="bulletin-wrapper" @click="showDetail>
    methods: {showDetail () {this.detailShow = true;}
    }

【Css Sticky footers布局】

  • Sticky footers设计:
  1. 如果页面内容不够长的时候,页面块粘贴在视窗底部;
  2. 如果内容足够长时,页面块会被内容向下推送(区别于fixed)
  • 相对复杂但兼容性最好的一个方案:
  1. 套路布局

    1

    2

    3

    4

    5

    6

    7

    8

    <div class="detail" v-show="detailShow">

            <div class="detail-wrapper clearfix"> //外层wrapper,min-height: 100%

                    <div class="detail-main"></div> //内容层 padding-bottom: 64px

            </div>

            <div class="detail-close">

                   <i class="icon-close"></i> //要适应内容显示的关闭按钮 margin-top: -64px

            </div>

    </div>

  2. 关键:padding-bottom撑开一个高度,为关闭按钮留下位置

    1

    2

    3

    .detail-main

         margin-top64px

         padding-bottom64px  

  3. 样式:

    + View Code

Star组件抽象 

  • 目标:为了增强扩展性,使足够灵活
  • 思路:
  1. v-for ——  根据分数 遍历itemClasses  显示星星样式

    <div class="star" :class="starType"><span v-for="itemClass in itemClasses" :key="itemClass.value" :class="itemClass" class="star-item"></span>
    </div>

  2. props —— 从父组件接收两个参数:size尺寸,score分数

     props:{size: {type: Number},score: {type: Number}
    }

  3. :class  —— 绑定动态class,  在不同的调用地方, 可以设置不同的样式

     View Code

  4. computed —— 根据size  计算出动态的class;根据score  push对应个数的全亮星星class;判断如果有半分或不足5分的,push进半星class和灰色星class;根据数组中对应的class显示对应的星星图片

    const LENGTH = 5;
    const CLS_ON = 'on';
    const CLS_HALF = 'half';
    const CLS_OFF = 'off';computed: {starType() {return 'star-' + this.size;  //根据size  计算出动态的class},itemClasses() {let result = [];let score = Math.floor(this.score*2)/2;let hasDecimal = score % 1 !== 0;let integar = Math.floor(score);for(let i=0; i<integar; i++){result.push(CLS_ON)  //根据score 在itemClasses中push进对应个数的全亮星星class}if(hasDecimal) {result.push(CLS_HALF);//判断如果有半分或不足5分的,push进半星class和灰色星class}while (result.length < LENGTH) {result.push(CLS_OFF)}return result; //根据itemClasses中对应的class显示对应的星星图片}}

  • 样式: 除了通用样式,还有根据不同size计算出的全部class的样式

小标题自适应线

  • 避免:写死百分比,这样宽屏幕会间隔很大,窄屏幕间隔会几乎看不到
  • flex布局:
<div class="title"><div class="line"></div><div class="text">优惠信息</div><div class="line"></div>
</div>

.titledisplay: flexwidth: 80%margin: 30px auto 24px auto.lineflex: 1position: relativetop: -6pxborder-bottom: 1px solid rgba(255, 255, 255, 0.2).textpadding: 0 12pxfont-size: 14px

【Postcss工具】

  • vue-loader 编译vue文件时,会使用Postcss工具,自动为有兼容性问题的css属性加上浏览器前缀
  • Postcss是根据can i use官网去写代码,基本不会出现兼容性问题
  • Can I Use 是一个检测浏览器对JS、HTML5、CSS、SVG或者其他Web前端相关特性支持程度的列表
  • 可以检测的浏览器包括桌面和移动版的主流浏览器:IE, Firefox, Chrome, Safari和 Opera等

过渡动画组件 transition

<transition name="fade"><div class="detail">
</transition>

.detailopacity: 1background: rgba(7, 17, 27, 0.8) &.fade-enter-active, &.fade-leave-activetransition: all 0.5s ease&.fade-enter, &.fade-leave-activeopacity: 0background: rgba(7, 17, 27, 0)

iPhone手机背景模糊效果

backdrop-filter: blur(10px)  // PC端和其它手机看不出效果

Vue2.0高仿饿了么核心模块移动端Web App项目爬坑(一)相关推荐

  1. 【饿了么】—— Vue2.0高仿饿了么核心模块移动端Web App项目爬坑(一)

    [饿了么]-- Vue2.0高仿饿了么核心模块&移动端Web App项目爬坑(一) 前言:学习Vue.js高仿饿了么课程过程中,总结了这个Web App项目从准备到开发完毕自己觉得很重要的知识 ...

  2. 【笔记-vue】《imooc-vue.js高仿饿了么》、《imooc-vue 音乐app》、《imooc-vue.js源码全方位解析》

    20170709 - 20171128:<imooc-vue.js高仿饿了么> 一.第一章 课程简介 1-1课程简介 1.需求分析-脚手架工具-数据mock-架构设计-代码编写-自测-编译 ...

  3. 一款基于Vue2.0高仿微信App的单页应用

    概述 利用Vue2.0模仿微信app,努力做到以假乱真的效果.个人独立开发,源码中有详细的注释,为新手提供许多有用的提示信息.项目的第一期接近尾声,后期会增加 仿3DTouch.登陆.注册.emoji ...

  4. 基于vue2+nuxt构建的高仿饿了么(2018版)

    基于vue2+nuxt构建的高仿饿了么(2018版) 前言 高仿饿了么,以nuxt作为vue的服务端渲染,适合刚接触或者准备上vue ssr的同学参考和学习 项目地址如遇网络不佳,请移步国内镜像加速节 ...

  5. Vue.js高仿饿了么外卖App学习记录

    (给达达前端加星标,提升前端技能) 开发一款vue.js开发一款app,使用vue.js是一款高效的mvvm框架,它轻量,高效,组件化,数据驱动等功能便于开发.使用vue.js开发移动端app,学会使 ...

  6. 高仿“饿了么”Vue项目(一)

    高仿"饿了么"Vue项目(一) 当我们把Vue框架的概念过了一遍之后,要进一步提升,就要看看别人是怎么使用Vue框架来做项目了. 在github上有不少好的Vue项目,我找到了其中 ...

  7. vue结合饿了么_Vue.js 高仿饿了么外卖app 全套_IT教程网

    资源名称:Vue.js  高仿饿了么外卖app  全套 资源目录: vue仿饿了么视频全套 全套 资源 │ files.txt │ project.zip │ resource.zip │ ├─第01 ...

  8. vue +vue-router + es6 +webpack 高仿饿了么app

    vue +vue-router + es6 +webpack 高仿饿了么app 刚通过某课网的教程学习了vue高仿饿了么app,由于教程是用Vue1.0编写的,现在Vue已经更新到了2.0,所以项目遇 ...

  9. 项目:Vue.js高仿饿了吗外卖APP(一)

    Vue.js高仿饿了吗外卖APP核心知识 使用Vue.js作为项目的技术栈!这是目前最火的MVVM框架(之一),轻量.简洁.高效.数据驱动.组件化的优点,被大家称为"简单却不失优雅,小巧而不 ...

最新文章

  1. Vue 组件库 HeyUI@1.16.0 更新日志
  2. NFL原则告诉我们做决策的时候,试图找到一个能解决所有问题,“大而全”的方案是不存在的。我们应当找到最关心的问题,因地制宜做出选择。——聚焦目标,取舍有道!...
  3. 电脑剪贴板在哪里打开_这个小玩意让手机的推送无缝显示在电脑上_办公软件...
  4. matlab watershed函数简单实现_函数指针方法实现简单状态机(附代码)
  5. php怎么获取分类数,php 两种获取分类树的方法
  6. tensorflow计算图_通过从头开始模仿其API来了解TensorFlow
  7. 【Flink】connection indicates remote task manager was lost
  8. 如何做专利挖掘,关键是寻找专利点,其实并不太难
  9. java实现简单泡泡屏保动画及点击变实心泡泡
  10. 赋值,浅拷贝,深拷贝区别和实现方法
  11. [ITIL学习笔记]ITIL认证相关
  12. 17_AOP入门准备_Salay案例(利用动态代理)
  13. Android 自动化测试 Espresso篇:简介基础使用
  14. 1.9G的视频被压缩为64K
  15. oracle快速复制一个表
  16. 移动端应该如何动态设置字体大小?
  17. 初创企业融资发展的几个阶段
  18. 职称计算机的考题整理分享,是2011年的,支持自学成才的人
  19. Ureport2导出内容加入PDF文件
  20. 100集华为HCIE安全培训视频教材整理 | 安全策略

热门文章

  1. P处理的中有大量判断条件是的sql写法
  2. c 语言编写数字单片机0-9,【学习笔记】单片机的40个经典实验之30:点阵式 LED“0-9”数字显示技术...
  3. oracle应付创建会计科目,R12 应付创建会计科目警告【已解决】
  4. prototype鼠标指针_html5鼠标点击页面光标圆点动画特效
  5. AD如何显示贴片数值并打印
  6. 关于拿鸡蛋数学题的解法
  7. 代码设置桌面壁纸或者屏保
  8. Aria2+motrix设置教程
  9. 涂鸦模组开发(压力传感器HX711)——4. 上报传感器数据给涂鸦模块
  10. 江兴华老师在武汉讲座