基于VUE2.0的高仿饿了么分析与总结
2019独角兽企业重金招聘Python工程师标准>>>
首先,慕课网提供的视频是基于vue1.0的规范写的,因此有一些地方在vue2.0下不能正常运行。虽然课程补充文件也提供了vue2.0的代码,但多多少少也有一些问题。参考他人写的代码以及官方文档,修改了部分内容,整个项目能够流畅运行,不会报错。
项目请移步我的github地址:https://github.com/gqbwoai2016/-VUE2.0-APP-。里面内容还不是很多,以后会继续丰富的。
-------------------------------------------------------------------------------------------------------------------------------------------------
废话就这么多,开始实质的内容吧:
涉及的工作有:由商家模块入手,进行需求分析,利用脚手架工具搭建,mock数据,架构设计,代码实现,自测以及编译打包。本项目注重代码规范:架构设计,组建抽象,模块拆分,代码风格统一,JS变量命名规范及CSS代码规范。
所涉及的技术有:vue-cli脚手架工具;vue-resource与后端数据交互(类似AJAX);vue-router插件管理路由;第三方库better-csroll;最大程度组件化(优点:可维护性和复用性);localstorage;flex弹性布局;
实现的功能
• Goods、Ratings、Seller组件视图均可上下滚动
• 商品页 点击左侧menu,右侧list对应跳转到相应位置
• 点击list查看商品详情页,父子组件的通信
• 评论内容够可以筛选查看
• 购物车组件,包括添加删除商品及动效,购物控件与购物车组件之间非父子组件通信,点击购物车图标,展示选择的商品列表
• 商家实景图片可以左右滑动
• loaclStorage缓存商家信息(id、name)
0、用vue-cli脚手架工具搭建项目结构,有以下结构
项目名称->build ------------------------------------------ webpack配置相关文件->config ------------------------------------------ webpack配置相关文件 ->node_modules ------------------------------------------ 依赖代码库->src ------------------------------------------ 存放源码->common ---- 通用的css和fonts->components ---- Vue 组件->router ---- vue-router相关配置(linkActiveClass,routes注册组件路由)->build ---- webpack 的打包编译配置文件->config ---- 一些配置项,比如我们服务器访问的端口配置等->dist ---- 项目经过 build 之后才会生成->prod.server.js----模拟的服务器配置,用来运行dist里面的文件,在config/index.js中,build对象中添加一条端口设置port:9000,->App.vue ---- 根组件,所有的子组件都将在这里被引用->index.html ---- 整个项目的入口文件,将会引用我们的根组件 App.vue->main.js ---- 入口文件的 js 逻辑,在 webpack 打包之后将被注入到 index.html 中->static ------------------------------------------ 存放第三方静态资源->.babelrc.JSON ------------------------------------------ babe的配制,用于从es6编译至es5->.editorconfig ------------------------------------------ 编译器配置->.eslintignore ------------------------------------------ 忽略语法检查的目录文件->.eslintrc.js ------------------------------------------ eslint的配置->.gitignore ------------------------------------------ git忽略的目录或文件->index.html ------------------------------------------ 入口文件,项目编译过程中会自动插入其中->package.json ------------------------------------------ 配置文件,描述一个项目->README.md ------------------------------------------ 项目描述文件
所有项目文件放在src下,main.js为入口文件,APP.vue为整个页面的vue,components存放组建文件,里面有许多子目录,子目录中存放.vue文件及图片等资源(满足组件化开发的就近维护)。common包含公共模块资源(js,scss,fonts等)。
- Hot-reload Vue的热更新,修改代码之后无需手动刷新网页,对前端开发来说非常方便
- PostCss,再也不用去管兼容性的问题了,只针对chrome这样的现代浏览器写css代码,会自动编译生成兼容多款浏览器的css代码
- ESlint,统一代码风格,规避低级错误(在eslintrc.js文件里面:rules是自定义的检查规则,可以覆盖默认的检查规则,例如要加分号,函数要加空格,这个跟代码风格有关)。在.eslintrc.js里的rules中写自定义规则,如'space-before-function-paren': 0,函数定义是括号前空格取消。
- Bable,ES2015出来已经有一段时间了,但是不少浏览器还没有兼容ES6,有了bable,放心使用ES6语法,它会自动转义成ES5语法
- SCSS,一款 CSS预处理器,编译后成正常的CSS文件。为CSS增加一些编程的特性
1、 数据mock
mock就是做假数据,这样可以便于前后端分离开发,前端不需要等后端做好数据来开发或者测试验证
假数据data.json.实现:sell(项目总文件)->插入data.json,然后在build->webpack.dev.conf.js中写数据接口,然后写数据的路由。
坑1,最新版的vue中dev-server.js被替换成了webpack.dev.conf.js,修改时注意
2、reset
sell->static->css->reset.css,写好后给index.html用link标签引用这个文件
3、meta
对其设置viewport以规范显示大小,缩放等移动端视口初始化。
4、header组件开发
a)使用vue-router实现点击切换;在这里,当前模块样式在vue-router中有个默认属性linkActiveClass,在main.js对其配置后,在APP.vue中通过<vue-link to:"/goods">创建点击部分以及<router-view>创建展示部分;
vue-router详解:
路由,其实就是指向的意思。我们页面中所有内容都是组件化的,我们只要把路径和组件对应起来就可以了,然后在页面中把组件渲染出来。
页面实现:定义了两个标签<router-link> 和<router-view>来对应点击和显示部分。<router-link> 就是定义页面中点击的部分,<router-view> 定义显示部分,就是点击后,区配的内容显示在什么地方。所以 <router-link> 还有一个非常重要的属性 to,定义点击之后,要到哪里去, 如:<router-link to="/home">Home</router-link>
js中配置路由:首先定义route,由path,component组成,前者指路径,后者指组件,如下所示,最后创建router管理路由。配置完成后,把router 实例注入到 vue 根实例中,就可以使用路由了
const routes = [{ path: '/home', component: Home },{ path: '/about', component: About }
]
//管理路由
const router = new VueRouter({routes // routes: routes 的简写
})
//配置完成,注入到实例中
const app = new Vue({router
}).$mount('#app')//$mount为手动挂载
//上面这个写法也可以改为
new Vue({el:"#box",router
});
注意:当首次进入页面的时候,页面中并没有显示任何内容。这是因为首次进入页面时,它的路径是 '/',我们并没有给这个路径做相应的配置。在这里使用重定向解决问题。
const routes = [{path:"/home",component: home},{path: "/about",component: about},// 重定向{path: '/', redirect: '/home' }
]
b)1像素实现:在APP端由于dpr不同,展示会有问题,因此添加minxin.scss设置通用样式后再通过base.scss使用@media 媒体查询来分别设置不同dpr的scale控制样式;
window.devicePixelRatio是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。公式表示就是:window.devicePixelRatio = 物理像素 / dips
非视网膜屏幕的iphone上等于1,在视网膜屏幕的iphone上,屏幕物理像素640像素,独立像素还是320像素,因此等于2。
2x和3x图是为了适应不同dpr比例的,不同比例的显示是不一样的.2x就是普通的dpr为1的屏幕使用的; 对于高清屏幕就是用3x,dpr为2或者以上; 2x和3x就是尺寸的大小,2x的图片比3x的小
c)满减图标在export default中create()内使用
classMap=['discount'...]
创建,在标签中通过
:class="classMap[seller.supports[0].type]"
引用。
d)背景模糊:整个header组件中有模糊背景图,可通过创建一个div然后绝对定位至相关位置,再用z-index=-1设置后,使用
filter:blur(15px)增加模糊效果。
e)css sticky footers模块:简而言之就是底部有一个固定图标,只有移动至底部区域才展示,否则不显示的一种布局。
父级 position:fixed,内容设 为padding-bottom:64px,页脚相对定位,margin-top:-64px,clear:both
为了保证兼容性,父级要清除浮动
坑2:新旧版vue-router不同,旧版支持router.map(),新版则使用const router=new VueRouter()直接在里面写即可
g)flex布局:
意为"弹性布局",用来为盒状模型提供最大的灵活性。设为Flex布局以后,子元素的float
、clear
和vertical-align
属性将失效。以下六个属性设置在容器上:
flex-direction 容器内项目的排列方向(默认横向排列)。可选值为row(默认)沿水平主轴由左向右排列、row-reverse沿水平主轴由右向左排列、column沿垂直主轴右上到下和column-reverse。
flex-wrap 换行方式。nowrap(默认)不换行、wrap换行(第一行在上方)和wrap-reverse
flex-flow 以上两个属性的简写方式 .box { flex-flow: <flex-direction> || <flex-wrap>;}将上述两种方法的值用||连接即可
justify-content 主轴上的对齐方式。主轴究竟是哪个轴要看属性flex-direction的设置了flex-start:在主轴上由左或者上开始排列;flex-end:在主轴上由右或者下开始排列;center:在主轴上居中排列;space-between:在主轴上左右两端或者上下两端开始排列;space-around:每个项目两侧的间隔相等。
align-items 交叉轴上如何对齐(纵轴对齐方式)flex-start顶对齐| flex-end底对齐 | center居中 | baseline文字基准线 | stretch撑开整个盒子
align-content 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
设置在子元素的属性也有六个:
order:项目排列顺序,数值越小排名靠前,默认为0;
flex-grow:项目放大比例,默认0;
flex-shrink:缩小比例,默认1;
flex-basis:计算主轴是否有多余空间,默认auto,项目本来大小;
flex:是上面三个简写,默认0 1 auto;
align-self:允许单个项目有与其他项目不一样的对齐方式。
f)自适应布局
左侧宽度固定,右侧宽度自适应
// 左侧固定width:80px,右侧自适应
parent:display:flex;
child-left:flex:0 0 80px
child-right:flex:1
5、goods模块
a)采用better-scroll实现滚动,在package.json表明版本,使用npm安装。BScroll接受两个参数,第一个是DOM对象,第二个是方式,在method中写方法,需要设置 click:true,否则移动端滑动无效。
注意:vue提供一种方法获取DOM,在需要获取地方添加ref="**",然后在js中通过this.$ref.**来引用;
DOM真正映射实在nextTick后,因此一些计算属性应该写在里面,否则在页面中无响应;
6、seller组件
a)商家实景图片横向滚动:
解决方案:每个 li 要 display:inline-block,因为width不会自动撑开父级ul,所以需要将计算后的宽度赋值给ul的width,(每一张图片的width+margin)*图片数量-一个margin,因为最后一张图片没有margin,同时new BScroll里面要设置scrollX: true, eventPassthrough: 'vertical', // 滚动方向横向
b)打开seller页面,无法滚动
问题分析:出现这种现象是因为better-scroll插件是严格基于DOM的,数据是采用异步传输的,页面刚打开,DOM并没有被渲染,所以,要确保DOM渲染了,才能使用 better-scroll;解决方案:用到mounted钩子函数,同时必须搭配this.$nextTick()
c)刷新后,无法滚动
问题分析:出现这种情况是因为mounted函数在整个生命周期中只会只行一次;解决方案:使用watch方法监控数据变化,并执行滚动函数 this._initScroll();this._initPicScroll();
d)缓存数据
使用window.localstorage保存舍设置缓存信息,封装在store.js中
e)axios
在vue1.x的时候,vue的官方推荐HTTP请求工具是vue-resource,但是在vue2.0的时候将推荐工具改成了axios。如果想像以前使用 vue-resource 那样 this.$http.get 调用,要这样定义:Vue.prototype.$http=axios;
通过 this.$http.get 来定义通过vue实例来发送get请求,然后通过then后面的回调函数将请求成功的数据接收,通过状态码来判断是否成功以及复制给vue的数据对象。由于这里是用的mock数据(模拟后台数据),所以用的模拟状态码。
const ERR_OK = 0;//表示没有错误信息,即获取数据成功
this.$http.get('/api/seller').then((response) => {response = response.data;if (response.errno === ERR_OK) {this.seller = Object.assign({}, this.seller, response.data);}
});
vue-resource详解:
vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说,$.ajax能做的事情,vue-resource插件一样也能做到,而且vue-resource的API更为简洁。
优点:体积小;支持主流浏览器;支持PromiseAPI和URI Templates;支持拦截器。
使用:
首先引入vue-resourec;然后发送请求即可
import VueResource from 'vue-resource';
Vue.use(VueResource);this.$http.get('/someUrl',jsonData).then(function(response){ //jsonData是传给后端的数据// 响应成功回调
}, function(response){// 响应错误回调
});
下面给个实例,从a.txt取数据
<!DOCTYPE html>
<html>
<head><title></title><meta charset="utf-8"><script src="http://unpkg.com/vue/dist/vue.js"></script><script src="https://cdn.jsdelivr.net/vue.resource/1.0.3/vue-resource.min.js"></script><script type="text/javascript">window.onload = function(){var vm = new Vue({el:'#box',data:{msg:'Hello World!',},methods:{get:function(){//发送get请求this.$http.get('a.txt').then(function(res){alert(res.body); },function(){console.log('请求失败处理');});}}});}</script>
</head>
<body> <div id="box"><input type="button" @click="get()" value="按钮"></div>
</body>
</html>
最新版Vue推荐使用axio,两个功能类似,首先也要安装然后引入,最后再使用:(注:他的注册不能使用Vue.use()方法)
import axios from "axios";
//注册
Vue.prototype.$axios = axios;
//使用axios
created:function(){this.$axios.get("/seller",{"id":123}).then(res=>{console.log(res.data);});
}
f)组件间通讯
父传子: props
// 父组件
<v-header :seller="seller"></v-header>// 子组件 header.vue
props: {seller: {type: Object}
}
子传父: $emit 如果是子组件想传递数据给父组件,需要派发自定义事件,使用 $emit 派发,父组件使用v-on接收监控(v-on可以简写成@)
// 子组件 RatingSelect.vue,派发自定义事件isContent,将this.onlyContent数据传给父级this.$emit('isContent', this.onlyContent);
this.$emit('selRatings', this.selectType);// 父组件 foodInfo.vue 在子组件的模板标签里,使用v-on监控isContent传过来的数据<v-ratingselect @selRatings="filterRatings" @isContent="iscontent"></v-ratingselect>
非父子组件之间通信: 1. 大型项目可以用 Vue官方推荐的vuex;event bus: 利用一个中间组件来作为信息传递中介;
g)better-scroll
better-scroll是一个移动端滚动的解决方案,基于iscroll的重写(多年没人维护了,有很多bug;有些情况是基于js实现的帧动画,体验差,bs基于css3等)
使用:首先应有一个父容器div,固定高度且overflow:hidden,给它设置bscroll,子元素高度由内容撑开。
<template> <div class="wrapper" ref="wrapper">//主div<ul class="content"> //子元素<li>...</li> <li>...</li>... </ul></div>
</template>
<script> import BScroll from 'better-scroll'export default {mounted() {this.$nextTick(() => {this.scroll = new Bscroll(this.$refs.wrapper, {})})} }
</script>
***重要:在mounted钩子函数里,this.$nextTick的回调函数中初始化better-scroll。是因为wrapper的DOM在这个时候已经渲染了,可以正确计算其高度。
异步数据处理
<template><div class="wrapper" ref="wrapper"><ul class="content"><li v-for="item in data">{{item}}</li></ul></div></template><script>import BScroll from 'better-scroll'export default {data() {return { data: [] } },created() {requestData().then((res) => { //requestData()是伪代码,实际用axios活vue-resourcethis.data = res.datathis.$nextTick(() => {this.scroll = new Bscroll(this.$refs.wrapper, {})})})}}</script>
初始化bs需要在数据获取之后。之所以放在created而不是mounted,是因为requestData是一个异步过程,拿到相应数据时,DOM已经渲染好,但是,数据改变后到DOM重新渲染仍然是异步过程,所以还是要异步初始化bs(nextTick)。
注意:在PC上,点击事件会执行两次。由于better-scroll派发的事件有event_constructed:true属性。可以进行处理。
if (!event._constructed) {return;}
7、sass
Sass的学名叫“CSS预处理器”,就是在CSS的基础上,引入了变量、嵌套、mixin(混合)、运算以及函数等功能,增加了代码的灵活性,可以让我们以更少的代码实现同样的效果,而且代码的整洁度、可读性更强。
.scss是Sass3引入的新语法,基本写法与CSS大致相同
基本语法:
a)变量。css属性的值(1px,bold)都可替换为变量。
$box-color: red; //定义变量
ul{color: $box-color; //引用
}
li{background-color: $box-color; //引用
}
b)嵌套
/***********************************************选择器嵌套*******************************************/
div {h1 {color: #333;}p {margin-bottom: 1.4px;a {color: #999;}:hover{color: #888;}}
}/* 编译后 */
div h1 { color: #333; }
div p { margin-bottom: 1.4px; }
div p a { color: #999; }
div p:hover{ color: #888; }/***********************************************属性嵌套*******************************************/
div {border: {style: solid;width: 1px;color: #ccc;}
}//编译后
div {border-style: solid;border-width: 1px;border-color: #ccc;
}
c)继承:使用选择器的继承,要使用关键词@extend,后面紧跟需要继承的选择器。
.class1 {border: 1px solid #333;
}.class2 {@extend .class1;background-color: #999;
}//编译后
.class1, .class2 {border: 1px solid #333;
}.class2 {background-color: #999;
}
d)Mixin混合器:使用@mixin声明,通过@include minxin名称调用
@mixin mixName { float: left;margin-left: 10px;
}div {@include mixName;
}//编译后:
div {float: left;margin-left: 10px;
}
/*带参数的声明及调用*/
@mixin left($value: 10px) {float: left;margin-left: $value;
}
div {@include left(66px);
}//编译后:
div {float: left;margin-left: 66px;
}
e)颜色函数
$box-color: red;
li{background-color: darken($box-color,30%);
}
//编译后
li{
background-color: #660000;
}
//更多
lighten(#cc3,10%)//#d6d65c
grayscale(#cc3)//#808080
complement(#cc3)//#33c
f)导入:@import "地址"; 如@import "../../common/scss/mixin.scss";
8、优化:
每次切换模块后,都会重新渲染DOM,解决方法为给APP.vue下的<vue-router 加入keep-alive></vue-router>,组建的切换状态就会保留。
9、打包:
使用npm run build打包文件,其执行了node build/build.js脚本,最终产生一个dist目录,里面包含css,js,index.html文件,打包后文件通过HTTP server启动(sell总目录下创建一个produ.server.js写完代码后使用node prode.server.js启动)
技巧:(1).如果要使用new创建对象,由于本项目使用了ESlint检查代码规范,因此会报错,在这里使用/*eslint-disable no-new*/来跳过校验;
(2). 在build->webpack.base.conf.js中,module.exports下的resolve的alias下可以定义路径,就不用每次引用时加./表示当前路径 等类似问题了;
(3).图标与文字不齐,可设置vertical-align:top来对齐,还不行可以对图片设置paddingtop。
(4).手机测试网页技巧:将localhost换成自己的ip,然后复制地址栏地址,进入草料二维码,然后生成二维码,然后用手机扫一扫就可以查看了,前提是,你手机和电脑必须在同一个局域网。
转载于:https://my.oschina.net/u/3728554/blog/1926349
基于VUE2.0的高仿饿了么分析与总结相关推荐
- 基于vue2+nuxt构建的高仿饿了么(2018版)
基于vue2+nuxt构建的高仿饿了么(2018版) 前言 高仿饿了么,以nuxt作为vue的服务端渲染,适合刚接触或者准备上vue ssr的同学参考和学习 项目地址如遇网络不佳,请移步国内镜像加速节 ...
- 【饿了么】—— Vue2.0高仿饿了么核心模块移动端Web App项目爬坑(一)
[饿了么]-- Vue2.0高仿饿了么核心模块&移动端Web App项目爬坑(一) 前言:学习Vue.js高仿饿了么课程过程中,总结了这个Web App项目从准备到开发完毕自己觉得很重要的知识 ...
- Vue2.0高仿饿了么核心模块移动端Web App项目爬坑(一)
原文https://www.cnblogs.com/ljq66/p/9980372.html 前言:学习Vue.js高仿饿了么课程过程中,总结了这个Web App项目从准备到开发完毕自己觉得很重要的知 ...
- 高仿“饿了么”Vue项目(一)
高仿"饿了么"Vue项目(一) 当我们把Vue框架的概念过了一遍之后,要进一步提升,就要看看别人是怎么使用Vue框架来做项目了. 在github上有不少好的Vue项目,我找到了其中 ...
- 【笔记-vue】《imooc-vue.js高仿饿了么》、《imooc-vue 音乐app》、《imooc-vue.js源码全方位解析》
20170709 - 20171128:<imooc-vue.js高仿饿了么> 一.第一章 课程简介 1-1课程简介 1.需求分析-脚手架工具-数据mock-架构设计-代码编写-自测-编译 ...
- Vue.js高仿饿了么外卖App学习记录
(给达达前端加星标,提升前端技能) 开发一款vue.js开发一款app,使用vue.js是一款高效的mvvm框架,它轻量,高效,组件化,数据驱动等功能便于开发.使用vue.js开发移动端app,学会使 ...
- vue +vue-router + es6 +webpack 高仿饿了么app
vue +vue-router + es6 +webpack 高仿饿了么app 刚通过某课网的教程学习了vue高仿饿了么app,由于教程是用Vue1.0编写的,现在Vue已经更新到了2.0,所以项目遇 ...
- Muse UI — 基于 Vue2.0 的 Material Design UI 库
Vue 2.0 发布以来,很多 vue 的开源项目都开始了升级计划,我也思考着 vue-carbon 的升级之路,9月开工,11月完工, Muse UI 闪亮登场. 先睹为快 Muse UI 主要用于 ...
- vue + vue-router + vue-resource + es6 + stylus + webpack 高仿饿了么外卖App商家详情
VUE高仿饿了么app 本项目github地址:https://github.com/motysla/eleme.git VUE 搭建简介 刚学习了VUE高仿饿了么app课,记录课的要点,巩固知识. ...
最新文章
- 《Unity 游戏案例开发大全》一6.5 游戏主场景
- 统计所有子串写到文件
- 从CSRF原理到CMS漏洞利用
- WPF 使用依赖属性(DependencyProperty) 定义用户控件中的Image Source属性
- Windows计算机功能Java源码
- 前端学习(494):在XHTML中得用法
- Linux 服务器拷贝远程文件 SCP
- 三维插值(MATLAB)——TriScatteredInterp/scatteredInterpolant函数
- 大数据整型的加减乘除
- 验证控件jQuery Validation Engine调用外部函数验证
- netbeans的python配置
- 新年跨出第一步:人工智能实施这样做!
- 11个炫酷的Linux终端命令大全
- win10安装c语言gmp库的使用,Window下使用GMP库
- Go语言在大数据时代应用前景
- 高德地图(第二篇)测量距离小工具
- 飞迈阁带你了解网上赚钱
- TDD模式下的射频前端VSWR检测功能难点
- 学模具好还是计算机网络好,模具编程要学多久才会?多长时间能学好?
- EOS 智能合约如何调试?
热门文章
- 操作系统(thuOS)笔记(一) 第三讲 启动、中断、异常和系统调用
- JAVA局域网飞鸽传书软件设计与实现免费源代码+LW
- linux软路由ospf,深入解析使用Linux+Zebra构建软路由系统
- 海康威视摄像头接海康云眸备忘录
- Linux进程:父子进程
- 操作简单,易上手的三款在线ps处理工具
- iscroll.js移动端滚动插件
- SuperPunch - unity3D拳击小游戏项目源码
- 这台计算机上没有安装高速USB主控器,提示安装“高速USB主控制器”的解决方法...
- Mysql写学生信息成绩管理系统(C语言)