goods 商品列表页开发

布局编写

除了商品之外还有购物车,还有个详情页,挺复杂的。

两栏布局:左侧固定宽度,右侧自适应,还是用flex。

因为内容可能会超过手机高度,超过就隐藏。左右两侧的内容是可以上下滚动。

good.vue:

为了兼容性问题呢,设置flex之后还设置了宽度,使得在不兼容flex的浏览器也能有80px的宽:

外壳就是这样了:

开始填内容了

同样的,我们还是利用vue-resource这个技术去拿到数据,获取goods数据:

goods需要用data去绑定,因为后面需要用到goods的数据在DOM上,需要添加getter,setter

也就是一开始这个goods为空,然后通过vue-resource获取。

左侧menu布局

还有个type字段,跟上一节的support是相似的。

接着写样式:

我们看到:

这里有一个需求,它需要垂直居中,那多行的怎么办呢?用table,table是垂直居中最好的布局。

右侧食品列表布局

食品列表是跟分类是有对应关系的,每一个分类有对应的标题,还有分类下所有的商品,这个商品有可能是数组。

关于右侧列表食品的标题样式

食品样式,因为图片右边的文字介绍的宽度是自适应的,所以还是会用到flex布局。

在每一个内容里面都有1像素,但是最后的元素是没有1像素的,所以应该去掉

在mixin.styl里:去掉1像素

在goods.vue

因为上下两个item中体格的向下margin跟另一个向上margin会重合,所以这里还要设置padding:

但是在最后一个的话它就会有显示了,所以要置为0:

接下来就来让这两块滚动

better-scroll运用

https://github.com/ustbhuangyi/better-scroll

inspired by iscroll, and it has a better scroll perfermance

作者为什么重写呢?因为iscroll已经很久没人维护了,bug也没人修复。

同样在package.json引入

因为这个库需要获取DOM,所以用vue2.0中的ref属性。

https://segmentfault.com/q/1010000007523462

http://www.sunzhongwei.com/how-to-get-input-value-in-vuejs

这里ref属性用的是等于号。

测试一下:

定义_ini()这样一个方法并且打印出来,执行就成功了。

这时可以查看元素:

已经添加一些样式了,但是还不能滚动,为什么呢?因为它在计算高度的时候,当我们去初始化这个BScroll的时候,它的DOM在vue更改数据的时候会跟着做映射,但实际上vue在更新这个DOM的时候是一个异步的,在回调里面更新,所以这里虽然改变了数据,但是DOM仍然没有变化,这是去初始化它的时候对它高度的计算就会有问题,所以这里需要用vue一个接口:

这样就可以滚动了。原理就是获得高度数据之后跟wrapper的高度作比较,大于就可以滚动。

接下来就是右边滚动时左边有高亮。

我们依赖的就是右边滚动的时候实时变化的Y值,也就是纵坐标。Y轴落到哪个区间左边就对应哪个区间。

要知道Y值落在哪个区间,就要知道每个区间的高度。

首先先计算整体区间的高度:用数组记录各个区间的高度,记录之后在监听这个滚动的时候能实时拿到这个Y坐标,然后去对比这个坐标落到那个区间,然后就可以得到当前左侧高亮的索引值是多少,然后在利用vue的class绑定把这个高亮的效果给写出来。

计算右侧索引的高度:

就在拿到数据后边去计算:

定义一个方法,这个方法用一个变量去存它,它是一个数组,是Y轴累加的过程

可以添加一个class:food-list-hook,用来被JS选择。

  1. let foodList = this.$refs.foodsWrapper.getElementsByClassName('food-list-hook');

第一个先存height=0,然后在累加每个区间

然后再实时拿到当前右侧的Y值,跟左侧索引做一个映射

定义一个变量:scrollY,并且跟踪它:

scrollY的变化就很简单。利用better-scroll的一个事件接口。

滚动的时候实时拿到这个scrollY:

接下来就要跟左侧做映射:

就要用到vue的计算属性

获取当前索引

设置样式,当currentIndex等于index是就设置样式,class=current:

接下来再实现左侧的点击功能

需要加一个click属性。

为了让移动端和PC端点击一样(PC端会触发两次)

这样就满足了:因为那个event的属性在PC端是没有的,这样就不用执行两次了。

最终:

总结:

当我们在写vue的开发应用的时候,遇到了某些好原生的库做交互的时候要注意几个点:

1、通过定义ref这个属性去访问到DOM,就可以拿到它了

2、this.$nextTick()这个借口:当我们想要去计算跟一些DOM相关的东西的时候,我们一定要把这个DOM渲染在里面,因为在VUE里面,虽然说DOM是数据的自然映射(改变数据就改变DOM),但是DOM真正发生变化其实是在nextTick这个回调函数后。所以在操作原生DOM的时候一定要调用这个借口。

购物车

设计稿:

这个会有多种状态。比如购买的话购物车的图标会亮,超过20元的话20元起送的区块会亮。

接下来我们就来创建一个购物车组件shopcart.vue :

然后在引入到good.vue组件,并在component注册

这样就可以写入了<shopcart></shopcart>

可以在查看元素看到shopcart这个组件:

接下来就来开发它的布局

可以看到,购物车右边content-right的宽度是固定的,左边content-left的宽度是自适应的。所以还是用flex布局。

因为购物车会一直在底部,所以要fixed定位,shopcart还要设置z-index,因为会有多层。

购物车图标Logo-wrapper这个区块会超出,所以需要设置宽高和定位,而且这里的box-sizing: border-box,还要设置个background: #141d27才看得到。

这里有个细节:就是class=”price”这个元素居中使用的是:

  1. margin-top: 12px
  2.  
  3. line-height: 24px

为什么不直接用line-height呢?因为这个price后面还有一个间隔线,需要用margin。

class=desc元素中的配送费是从父组件传过来的,所以在good.vue初始化shopcart组件时可以传入一些参数。传个配送费和起送费

这样就可以在shopcart.vue用了

但是还是报错了:

是因为我们要在外层的app.vue中传入seller数据,这样我们才可以在goods.vue组件获得这个seller

这样问题就解决了。

但是呢,这里的数据没有显示:

这是因为我们还要在shopcart.vue接受这个seller,否则是没有用的

这样数据就是通过一层层地传递,通过router-view把seller传到goods.vue组件,再由good.vue再把seller穿戴shopcart.vue组件,shopcart.vue拿到这个变量就可以用了。

还有个“起送价”的区块

这样基础样式就搞定了:

接下来就要给购物车添加状态,这些状态是对选择商品有一个映射。这里选择多少商品也是通过props去获取父组件的数据,毕竟你是在父组件选择商品的而不是在购物车选择商品的

这里的default就是个函数了。因为在vue.js里面,如果props是一个Array或者Object,default就需要是一个函数。

计算总价:

这样就可以了。

再给它写入一些数据测试一下:

接下来还有为购物车的状态添加一些样式

所有这些状态变化都是与selectFoods的数据相关的,比如:

再添加一些值,购物车就会变化:

这里照样还是要计算,先计算一个totalCount,表示所有商品的总和。就是对selectFoods里面拿到的count做累加。

这时候需要在模板里面再写一个div来显示这个totalCount:

结果:

接着:购物车的totalCount大于0时就会高亮:

还有price也要加高亮,跟上面相似。

这里还有一个细节:购物车清空的话,上面的小红标也要去掉,这里需要加v-show:

还有右边的content-right

它有三种状态,当没有商品的时候,它是初始状态;接着选了商品之后是显示还差多少元起送;最后达到起送价是显示高亮“去计算”。

这里依然用计算属性去描述它

补充:ES6对字符串的拼接有个扩展,就是用” ` ”,引号反过来写。

接下来就是样式了

还需要绑定class,因为这里有两个状态,所以这里可以绑定一个变量。一个是起送价还没到的原始状态,另一个是商品价格超过起送价的高亮状态:

并且计算属性:

这样就完成了 ,这个过程都在围绕父组件传过来的selectFoods进行状态变化,这里vue数据驱动确实带来很多方便。

接下来就要添加按钮了,因为项目中多次用到,所以也要抽象成一个组件cartcontrol.vue

这个按钮是和商品有关联的,也有个数。所以这个cartconcontrol组件要接受一个数据。也就是说,我们调用这个购买组件的时候,要传入关联的food,因为我们去给它增加和删除都是关联它的个数food.count.

在good.vue引入组件。

有的按钮有时是不会显示的,比如food.count为0的时候,减号按钮和数值不会显示:

在goods.vu e组件中,我们还要给它包装一层div,因为还得设置样式呢。而且还要把food对象传入

可以在查看元素里面看到很多对象。

接下来添加样式:

有个技巧性东西,就是因为按钮很小,所以我们来增加padding,让它的点击区域变大,增加用户体验。

在goods.vue组件添加样式

接下来写逻辑:点击加好food.count会加1,并且减号和数字显示

但是这样点击会没有响应,因为我们这个addCart是在food-wrapper面板里面,那这个面板是使用better-scroll插件,这个在移动端点击的话需要给他在初始化better-scroll的时候传一个参数。这就需要在goods.vue组件添加click:true

同样的,这样点击的话在PC端也会点击一次又两次响应。

所以还是老办法,通过event去判断

这样就只有一次了。

但是页面上的减号却没有出来。这其实是vue.js的一个特性,也就是说当我们去给一个观测对象添加一个它不存在的字段的时候(比如food.count),我们这样直接赋值是不可以的,它是检测不到增和减的变化的。所以在新增和删除某个字段的时候,我们想要它观察到这个变化,我们就需要用一个接口,先cartcontrol.vue引入全局的vue。

然后就用vue.set这个接口,这样就能被观测到

数字的样式:

接下来实现减的逻辑

这样就搞定了

现在把按钮和购物者关联起来

当我们使用cart按钮时,修改的是food.count属性,这里的food是父组件传过来的对象

当我们更这个对象增加属性(count),也就修改对象本身,它就会影响父组件good.vue。在调cart的时候需要传selectFood

就是去遍历,然后获得foods,这个foods是什么呢?

然后点击加号,就会有

就是先把foods清空,然后在遍历全部商品,再将得到的商品分组继续遍历,将有选择的加入到foods数组,这样再把foods数据传给shopcart.vue

这里的foods数组中的每一项都是一个完整地food对象,所以不仅仅包括price和count。

总之,这个过程就是将shopcart组件和cartcontrol组件的数据结合起来。 计算属性selectFoods观测goods对象,一旦goods对象发生变化(因为我们在之前用到foods.count,有变化就说明goods变化),就会被重新计算,把逻辑重新执行一遍,并且遍历每一个单个的food,有count的话就说明这个food被我们选择了,这时就加入数组。

流程大概就是这样:在cartcontrol.vue中,我们会通过点击按钮去改变food.count --> goods.vue监听到可也会改变相应的数据,也就是选择的数据 --> selectFoods会遍历所有food对象并把有变化的数据对象加入到数组中 --> shopcart.vue检测到这些数据的变化就会获取并呈现在购物车。

项目vue2.0仿外卖APP(六)的更多相关文章

  1. 项目vue2.0仿外卖APP(一)

    最近用vue.js做一个仿饿了么外卖APP的项目,现在也把流程啊什么的暂时先整理一下在这个博客上面. 当然,这个过程会有点长,不过确实能学到很多东西. 话不多说,马上开始吧. 1.项目介绍 选用当前最 ...

  2. 项目vue2.0仿外卖APP(五)

    header组件 vue-resourse应用 https://github.com/pagekit/vue-resource vue-resource是Vue.js的一款插件,它可以通过XMLHtt ...

  3. 项目vue2.0仿外卖APP(四)

    组件拆分 先把项目搭建时生成的代码给清了吧 现在static目录下引入reset.css 接着在index.html引入,并且设置<meta> 有时候呢,为了让代码符合我们平时的编码习惯, ...

  4. 项目vue2.0仿外卖APP(二)

    vue-cli开启vue.js项目 github地址:https://github.com/vuejs/vue-cli Vue.js开发利器vue-cli,是vue的脚手架工具. 在工地上,脚手架是工 ...

  5. 项目vue2.0仿外卖APP(三)

    项目的结构如下:                   项目资源准备 准备项目的各种图片资源等等 注意:在webpack可以不用css sprite,直接用单张图片,因为它会帮忙打包. 还有SVG图片, ...

  6. 项目vue2.0仿外卖APP(七)

    ratings评价列表页实现 在ratings.vue组件里开发 首先先引入seller数据: 书写模板结构: 由于评价页又有之前写过的star.vue组件,所以又要在ratings.vue组件引入: ...

  7. Vue2.0仿饿了么webapp单页面应用

    Vue2.0仿饿了么webapp单页面应用 声明: 代码源于 黄轶老师在慕课网上的教学视频,我自己用vue2.0重写了该项目,喜欢的同学可以去支持老师的课程:http://coding.imooc.c ...

  8. vue2.0仿今日头条开源项目

    vue-toutiao 这是用 vue.js 2.0 高仿 今日头条 的移动端项目,结合了原生app的部分功能以及网页版. 前言 本人是 今日头条 的重度用户,在学习vue.js过程中,在GitHub ...

  9. vue2.0 之 douban (六)axios的简单使用

    由于项目中用到了豆瓣api,涉及到跨域访问,就需要在config的index.js添加代理,例如 proxyTable: { // 设置代理,解决跨域问题 '/api': { target: 'htt ...

随机推荐

  1. [LeetCode] Best Time to Buy and Sell Stock II 买股票的最佳时间之二

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  2. [LeetCode] Multiply Strings 字符串相乘

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  3. IT培训行业揭秘(五)

    前面说了一大堆,简单揭露了一些目前培训行业鱼龙混在的情况,那么今天我就站在一个即将毕业的大学生角度来谈谈如何选择一个靠谱的培训机构. 你即将大学毕业了,在大学里面浑浑噩噩的混了几年,马上就要离开校园, ...

  4. 如何理解 卷积 和pooling

    转自:http://blog.csdn.net/malefactor/article/details/51078135 CNN是目前自然语言处理中和RNN并驾齐驱的两种最常见的深度学习模型.图1展示了 ...

  5. eclipse环境搭建

    百度经验http://jingyan.baidu.com/article/bea41d437a41b6b4c51be6c1.html 1.JAVA JDK 2.Andriod SDK eclipse里 ...

  6. 在 Sublime Text 3 中配置编译和运行 Java 程序

    参考网址:http://www.open-open.com/lib/view/open1388105023765.html 1. 设置 java 的 PATH 环境变量 2. 创建批处理或 Shell ...

  7. C#-WebForm-简单控件

    在HTML中称"元素",添加了"runat='server'"后称控件,后台服务端可以控制 想要后台改变前端的控件,需要先让后台获取前端控件 常用的简单的表单元 ...

  8. 使用Eclipse进行远程调试

    转自:http://blog.csdn.net/sunyujia/article/details/2614614 今天决定做件有意义的事,写篇图文并茂的blog,为什么要图文并茂?因为很多事可能用语言 ...

  9. 【USACO 3.2】Spinning Wheels(同心圆旋转)

    题意: 5个同心圆,告诉你角速度,每个圆有1至5个楔,告诉你起点和宽度.求最早时间如果有的话使得存在某个角度经过5个圆的楔. 题解: 最重要的是要意识到,360秒钟后,每个圆都回到了原来的位置. 我的 ...

  10. mac搭建测试服务器

    代码可以参考: https://github.com/BigShow1949/MyServe  这里也有jar包 一.下载一个jar包 点击链接下载服务器端[moco服务端] https://repo ...