项目总结:vue.js2.5饿了么APP(1)概述+项目准备
项目总结:vue.js2.5饿了么APP(1)概述+项目准备
一、概述
1. 项目简介
使用vue.js vue是当前最火的MVVM框架,(优点:轻量、简洁、高效、数据驱动、组件化)
本项目做的是:高仿上线外卖APP商家模块
开发过程:需求分析-脚手架工具-数据mock-架构设计-代码编写-自测-编译打包
以线上生产环境来开发:代码开发及测试环节:UI标注完美还原设计图、以真实外卖APP数据做演示,以保证代码无兼容性问题。
代码规范:(1)架构设计;(2)组件抽象;(3)模块拆分;(4)代码风格统一;(5)JS变量命名规范;(6)CSS代码规范;致力于编写高可维护,易于扩展,通用性强的代码,了解真实项目流程。
2. 功能技术分析
一期
(1)Vue-resource和后端做数据交互,
(2)使用Vue-router做前端路由实现单页面应用,
(3)使用第三方库better-scroll来实现列表滚动,
(4)最大程度组件化(页面上有很多样式和功能相似的区块,方便在项目中复用),
(5)商家页面中,收藏商家这个功能会使用html5的localstorage接口,存储在浏览器端,
(6)对于图标字体的应用,
(7)移动端1像素边框,
(8)css sticky footer布局,
(9)flex弹性布局。
二期
技术栈:vue.js 2.5.17 vue-cli 3.0 cube-ui
(1)Vue.js高级知识(组件封装,组件通信,插槽,过渡动画,mixin)
(2)对于vue-cli3.0脚手架的应用(不仅用来初始化项目和开发调试,还做一些额外的webpack配置,并且利用它来mock数据,在项目完成之后还会做打包构件分析);
(3)充分利用cube-ui的七个组件和一个模块(使用第三方开源组件库)
3. 学习内容
学习目标:(1)掌握vue.js在实战中的运用;(2)学会使用Vue.js完整开发移动端APP;(3)学会组件化、模块化的开发方式;(4)学会使用第三方组件库辅助开发;(5)学会项目部署和构建过程
学习内容:(1)Vue.js框架介绍;(2)vue-cli脚手架搭建基本代码框架;(3)vue-router官方插件管理路由;(4)vue-source ajax通信;webpack构建工具;(6)ES6+eslint 规范代码风格,代码风格审查工具,静态语法检查。
移动端常用开发技巧:(1)flex弹性布局;(2)css stickyfooter布局;(3)炫酷的交互设计;
4. 近年来前端开发趋势
(1)旧浏览器逐渐被淘汰,移动端需求增加(IE6-8不支持ES5特性)
(2)前端交互越来越多,功能越来越复杂(高大上的技术库和框架,酷炫的运营活动页面,H5小游戏,新闻趣味站,在线购物平台,社交网络,金融信贷应用,音乐互动社区,视频分享平台,打车出行平台)
(3)架构从传统的后台MVC向REST API + 前端MV*(MVC MVP MVVM)迁移(使用ajax方式,和后端REST API通讯,异步刷新页面的某个区块,来优化和提升体验)
5. MVVM框架
Model 是数据部分,对应到前端就是JavaScript对象;View是视图部分,对应前端的DOM,ViewModel就是连接视图和数据的中间件。
在MVVM的架构下,数据和视图是不能够直接通讯的,通常通过viewmodel做通信,viewmodel通常要实现一个observer观察者,当数据发生变化,viewmodel能够观察到数据的变化,然后通知到对应的视图做更新,而当用户操作视图,viewmodel也能监听到视图变化,然后通知数据做改动,这就实现了数据的双向绑定。
应用场景:针对具有复杂交互逻辑的前端应用;提供基础的架构对象;通过Ajax数据持久化,保证前端用户体验。
(当前端和数据进行操作的时候,可以通过ajax请求和后端做数据持久化,不需要刷新整个页面,只需要改动DOM里面需要改动的部分,特别是移动端应用场景,刷新页面的代价太昂贵,会重新很多资源,虽然有些资源会被缓存,,但是页面的DOM,JS,CSS都会被重新解析一遍,因此移动端页面都会做成SPA单页面应用,因此诞生了很多SVVM框架,如angular.js, react.js, vue.js)
6. 什么是vue.js
(1)它是一个轻量级MVVM框架;
(2)数据驱动+组件化的前端开发
(3)GitHub超过25k star,社区完善
对比Angular 和React
vue.js更加轻量,gzip后大小之后20K+,因此对于移动端来说vue更加适合;
vue.js容易上手,学习曲线平稳;(angular入手较难)
吸收两家之长,借鉴angular的指令和react的组件化;
Vue.js的核心思想
(1)数据驱动:DOM是数据的一种自然映射
如果没有Viewmodel是如何交互的?视图改变会手动触发DOM改变。
使用了Vue.js之后,就省去了手动操作DOM的步骤,在vue.js中只用改变数据,vue.js通过Directive指令,对DOM进行封装,当数据发生变化,会通知指令修改对应的DOM,数据驱动DOM变化,DOM是数据的一种自然映射。Vue.js还会对操作做一些监听,当我们修改视图的时候,vue.js监听到这些变换,从而改变数据,这样就形成了数据的双向绑定。
数据响应原理:数据改变驱动视图更新。
有一份数据a.b,在一个vue对象实例化的过程中,会给b通过object。Defineproperty属性添加了getter和setter,同时vue.js会对模板进行编译,解析生成一个指令对象v-text指令,每个指令对象都会关联一个watcher,当我们对对应的表达式a.b求值的时候,就会触发getter,把依赖收集到watcher里面。当再次改变a.b的值的时候,会触发setter,会通知到对应的watcher,watcher会再次对a.b求值,计算对比新旧值,当发现值改变,watcher会通知到指令,使用指令的update方法,由于指令是对DOM的封装,所以就会调用原生DOM的方法更新视图,这样就完成了数据改变到数据更新的一个自动化的过程。
(2)组件的设计原则:页面上每个独立的可视/可交互区域视为一个组件;每个组件对应一个工程目录,组件需要的各种资源在这个目录下就近维护(前端工程化和分治思想);页面不过是组件容器,组件可以嵌套自由组合形成完整页面。
7. cube-ui组件库
- Popup 弹层:底层弹层组件,主要用于基于此组件实现上层组件封装,只提供了基础功能:指定类型、是否有背景层、显示内容(HTML)以及是否居中。
- 内置所有的弹层类组件都是基于此组件实现,包括:Toast、Picker、TimePicker、Dialog、ActionSheet。
- Scroll 滚动:滚动列表,提供了优质的原生滚动体验,便捷的配置项和事件,是一个基于better-scroll进行封装的组件。
- Slide 幻灯片:轮播图,提供了常见的轮播及swipe的功能,也是一个基于better-scroll进行封装的组件。
- IndexList 索引列表:索引列表,提供了列表索引的功能,也是一个基于better-scroll进行封装的组件。
- create-api:有些时候,开发者可能也需要自己封装的组件支持 API 式调用,此时可以通过引入 create-api 模块或者通过全局的 Cube.createAPI 接口来达到封装目的。
- Dialog:Dialog模态框组件,提供了多种样式及交互形式。
二、项目准备
1. 需求分析
1)区块划分
6张设计稿;区块划分为:头部区、内容区(商品页、评论页、商家详情页)
点击导航栏会进行切换,由于是SPA单页面应用–切换页面时不会刷新整个页面;
(1)头部区:包括商家描述,当点击公告和数字的时候会展示黑色的浮层,点击按钮浮层关闭;
(2)内容区
商品页:可以拆分为左右两栏,左侧是商品的分类,右侧是实际商品的列表。当商品区块对应某个分类时,左边导航栏相应分类会高亮,当列表内容超过页面可视区块时,可以进行滚动,在滚动右侧时,左侧的高亮区也会保持联动的效果。商品页底部是一个购物车,当点击加号购买商品的时候,购物车会联动购买的商品总数和金额,当金额超过最小配送费时,显示“去结算”按钮,点击按钮可以进行结算;当购物车商品部位0 时,点击购物车是没有反应的;点击购物车会弹出购物车列表,列表也有最大高度,当超过最大高度,内部可以滚动,在购物车内部也可以进行添加和删除操作,并且和主页面保持联动。当我们点击具体的商品,会展示具体商品页浮层,有商品图片、介绍,可以点击加入购物车,一样可以完成一次购买流程,底部是一个评论区,我们可以条件查看,比如根基评级类型(有无内容)进行勾选,评论区的显示会相应做出变化,当浮层页面超过手机高度时,页面可以滚动,页面左上角有一个返回按钮,点击按钮浮层会关闭。
商品评论页:上面是一个评星级别,下面是具体的评论区。
商家详情页:主要是商家信息的展示,商家实景图是当图片官渡超过页面宽度时可以左右滚动,当整个页面超过手机高度,可以上下滚动,有一个收藏区块,可以点击收藏关注商家。
2)组件拆分
由于是组件化的开发,整个页面可以看成App.vue一个大组件。
大组件包含头部(header),导航区(主要控制下面内容部分的切换),内容部分包含商品(goods),评价(ratings),商家(seller)三个组件。
2. 图片素材
1)设备像素比
移动端一张图片需要2x和3x,来适应不同dpr(device picture ratio设备像素比)推荐文章:张鑫旭-设备像素比简单介绍
https://www.zhangxinxu.com/wordpress/2012/08/window-devicepixelratio/
参考链接:https://www.cnblogs.com/samwu/p/5341056.html
2)SVG图片
SVG是一种矢量图片,它的特点就是当我们把它放大之后图片质量不会下降,在移动端开发过程中,通常会把一些色彩单一的图片做成SVG图片,在CSS中引入图标字体文件。
推荐IcoMoon工具: https://icomoon.io/
网站具体使用方法:点击Icomoon app按钮,会跳转到如下页面,点击Icomoon icon按钮,之后选中所有的SVG文件;选中自己想要的图标后,点击右下角的generate font,可以查看代码。点击preference可以修改字体名称等;点击download按钮,解压后fonts里面就是所有的图标字体文件以及style.css。
3)support-ico组件对图标处理
由于项目中的图标(icon)多次使用,并且尺寸(1,2,3,4,四种尺寸)和类型(减、折、特、票),基于此,就不同把这些图标做成一个组件support-ico。
<template><span class="support-ico" :class="iconCls"></span></template>
含有一个动态绑定的class,可以根据传入的props(size,type)改变绑定的class。
Computed计算属性icon Cls(),定义一个数组,数组保存了{‘decrease’, ‘discount’, ‘special’, ‘invoice’, ‘guarantee’},可以根据传入的type和size动态拼接icon的样式。
-
computed: {
-
iconCls() {
-
const classMap = [‘decrease’, ‘discount’, ‘special’, ‘invoice’, ‘guarantee’]
-
return `icon-${this.size} ${classMap[this.type]}`
-
}
-
}
实现对于不同的类型和大小引入不同的图片。
3. mock数据
准备了一个data.json里面是我们模拟的数据。包含三个部分:seller,goods,ratings
在vue.config.js中写入devServer字段,并且有一个before函数,可以通过app.get来模拟get接口,返回json字段,其中goods,ratings,seller都是通过data.json字段拿到的。
测试:启动服务之后输入localhost:8080/api/seller会返回json数据。表示mock服务成功了。
4. 使用vue-cli搭建项目框架
安装并创建项目,参考链接: https://cli.vuejs.org/zh/guide/installation.html
项目入口html在public目录下的index.html, index.html编译之后会引用main.js(入口js是src目录下的main.js)
.browserslistrc 浏览器,用CSS在不同浏览器可能存在兼容性问题,因此需要对其加前缀—针对于postcss.config.js中的autoprefixer插件()
Eslintrc.js就是eslint的配置
Package.json就是需要的依赖,项目描述
5. 安装cube-ui
移动端比较好用的组件库https://didi.github.io/cube-ui/#/zh-CN
Theme.styl 列出所有组件的颜色,可以进行修改
Package.json中添加了一个transormModules字段,引用cube-ui组件
Vue.config.js 可以进行额外配置
6. 项目common目录
1)fonts
存放SVG相关图片的信息
2)stylus
Index.styl 入口文件,里面import icon和base(在main.js需要引入index.styl)
Icon.styl是字体图标的样式(引用了font下面的文件,制作的图标可以通过类名可以访问到icon)
Base.styl定义了基础样式(html和body)
mixin.styl导入了cube-ui的stylus(@import “~cube-ui/src/common/stylus/mixin.styl”)
Variable.styl导入cube-ui的一些变量(@import “~cube-ui/src/common/stylus/variable.styl”),同时自己定义了项目的颜色
7. axios封装和数据获取
Axios第三方库获取数据:https://github.com/axios/axios
npm i axios –save
在目录下创建api-helper.js和index.js,对于所有的get方法进行封装
-
/*helper.js*/
-
import axios from ‘axios’
-
-
const ERR_OK = 0
-
-
export function get(url) {
-
return function(params) {
-
return axios.get(url, {
-
params
-
}).then((res) => {
-
const { errno, data } = res.data
-
if (errno === ERR_OK) { // 成功
-
return data
-
}
-
}).catch(() => {
-
})
-
}
-
}
-
/*index.js*/
-
import { get } from ‘./helpers’
-
-
const getSeller = get(‘/api/seller’)
-
const getGoods = get(‘/api/goods’)
-
const getRatings = get(‘/api/ratings’)
-
export {
-
getSeller,
-
getGoods,
-
getRatings
-
}
8. 1像素border实现
border-bottom: 1px solid rgba(7, 17, 27, 0.1)
在PC端是1像素边框,但是在手机端有设备像素比,所以可能看上去会有不同
设计一个mixin.styl
-
border-1px($color)
-
position: elative
-
&:after
-
diaplay: block
-
position: absolute
-
left: 0
-
bottom: 0
-
width: 100%
-
border-top: 1px solid $color
-
content: ‘ ‘
对于需要添加1像素边框的标签加上border-1px类,然后对伪类进行缩放
-
@media(-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5)
-
.border-1px
-
&::after
-
-webkit-transform: scaleY(0.7)
-
transform: scaleY(0.7)
-
@media(-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2)
-
.border-1px
-
&::after
-
-webkit-transform: scaleY(0.5)
-
transform: scaleY(0.5)
1像素border实现:伪类(绝对定位)+ 缩放(对伪类Y轴缩放),
另一种思路是在html的header里添加如下一句:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
参考连接:https://www.cnblogs.com/wisewrong/p/6425315.html
https://www.jianshu.com/p/fa670b737a29
后续章节传送:
项目总结:vue.js2.5饿了么APP(2)主要组件实现 – 头部相关组件
项目总结:vue.js2.5饿了么APP(3)主要组件实现 – 购物车相关组件(上)
项目总结:vue.js2.5饿了么APP(4)主要组件实现 – 购物车相关组件(下)
项目总结:vue.js2.5饿了么APP(5)主要组件实现 – 商品详情页部分
项目总结:vue.js2.5饿了么APP(6)主要组件实现 – 评价页+商家页部分
项目总结:vue.js2.5饿了么APP(7)项目部署与总结
项目github链接: https://github.com/Rachel-X-4869/cube-ui-eleme-project