说明:本总结来源于慕课网 @ustbhuangyi老师的课程《Vue.js2.5+cube-ui重构饿了么App》课程,本博客做了项目总结梳理便于回顾,需要学习的伙伴可以移步学习。与君共勉!

之前章节传送:

项目总结:vue.js2.5饿了么APP(1)概述+项目准备

项目总结:vue.js2.5饿了么APP(2)主要组件实现 - 头部相关组件

项目总结:vue.js2.5饿了么APP(3)主要组件实现 - 购物车相关组件(上)

购物车组件主要包含(shop-cart ,shop-control , shop-cart-list , shop-cart-sticky)4个部分,本节主要讲解后两个,以及一些购物车相关优化设计 。


速看

shop-cart-list组件+shop-cart-sticky组件  当购物车中有商品时,点击购物车会弹出购物车详细内容,列表限制高度并可以滚动。(起初一期时没有将这一部分抽离出来,因此就在shop-cart组件的后半部分,通过一个标记来控制区块显示)二期,对于这种弹层类组件选择使用cube-ui的<popup>组件实现,并将其设置为API调用,设置hide() show()方法来控制蒙层显示。

但是有个问题:shop-cart-list是API组件,会动态的向body中挂载结点,因此层级较高,高过内层组件层级。但是购物车组件是一个子组件,因此会遮盖到原来的购物车组件(这个组件有个向上突出的部分)。由于无法调整层级,解决方法就是:使用shop-cart-sticky组件。动态向body中挂载一个购物车组件的副本。

并且这一部分还要加入的功能有:(加入购物车的小球动画,结算,清空购物车)对于小球下落动画,可以调用cart-control的drop方法,两个弹出dialog的操作都使用了cube-ui中的dialog组件。而对于切换tab的购物车联动问题,只需要在请求数据之前判断是否已经拿到数据。

最后,对于header和shop-cart-list的弹层组件中都用到的hide() show() 方法用mixin抽离出来做代码简化。


目录

一、购物车详情shop-cart-list组件(二期)

1. 概述

2. 布局

3. 实现

(1)popup组件使用

(2)过渡动画

(3)列表滚动

(4)组件的使用

(5)添加弹出触发方法

(6)存在的问题

(7)商品购买时小球飞入动画

(8)清空购物车

(9)结算按钮

(10)公共部分mixin抽离

(11)滑动页面购物车关联

二、购物车详情shopcart-list区块(一期)

1. 概述

2. 布局

3. 实现

(1)实现组件显示隐藏

(2)实现动画

(3)蒙层的实现

三、shop-cart-sticky组件

1. 概括

2. 布局

3. 实现

四、createAPI详解


一、购物车详情shop-cart-list组件(二期)

1. 概述

当购物车中有商品时,点击购物车会弹出购物车详细内容,列表限制高度并可以滚动。(起初一期时没有将这一部分抽离出来,因此就在shop-cart组件的后半部分,通过一个标记来控制区块显示)二期,对于这种弹层类组件选择使用cube-ui的<popup>组件实现,并将其设置为API调用,设置hide() show()方法来控制蒙层显示。但是有个问题:shop-cart-list是API组件,会动态的向body中挂载结点,因此层级较高,高过内层组件层级。但是购物车组件是一个子组件,因此会遮盖到原来的购物车组件(这个组件有个向上突出的部分)。由于无法调整层级,解决方法就是:使用shop-cart-sticky组件。动态向body中挂载一个购物车组件的副本。

并且这一部分还要加入的功能有:(加入购物车的小球动画,结算,清空购物车)对于小球下落动画,可以调用cart-control的drop方法,两个弹出dialog的操作都使用了cube-ui中的dialog组件。而对于切换tab的购物车联动问题,只需要在请求数据之前判断是否已经拿到数据。

最后,对于header和shop-cart-list的弹层组件中都用到的hide() show() 方法用mixin抽离出来做代码简化。

2. 布局

当购物车中有商品时,点击购物车会弹出购物车详细内容。

布局:顶部是一个标题区+列表(有一个最大高度,超过最大高度列表可以滚动,如果列表高度不满足最大高度,只能被列表自身的高度撑高)

 <transition name="fade"><cube-popup><transition name="move" @after-leave="onLeave"><div v-show="visible"><div class="list-header"><cube-scroll class="list-content" ref="listContent"><ul><li class="food" v-for="food in selectFoods" :key="food.name"><span class="name"></span><div class="price"></div><div class="cart-control-wrapper"><cart-control @add="onAdd" :food="food"></cart-control></div></li></ul></cube-scroll></div></transition></cube-popup></transition>

使用cube-scroll组件实现列表滚动,并且其中添加shop-control组件做商品的购买。

使用cube-ui将购物车组件变成一个createAPI模块的调用,并使用cube-popup弹层组件

3. 实现

(1)popup组件使用

<cube-popup>组件是所有弹层组件的基础组件. position是弹窗出现的置,:mask-closable=true点击蒙层会派发click=maskclick事件,而达到关闭的效果,z-index弹窗高这里的type类似于class,可以改变样式(设置bottom样式达到我们的效果),并通过v-show控制弹层显隐,以及驱动过渡动画<transition>。

<cube-popupv-show="visible":mask-closable=true:z-index=90position="bottom"type="shop-cart-list"@mask-click="maskClick">
</cube-popup>

(2)过渡动画

.cube-shop-cart-listbottom: 48px&.fade-enter, &.fade-leave-activeopacity: 0&.fade-enter-active, &.fade-leave-activetransition: all 0.3s ease-in-out.move-enter, .move-leave-activetransform: translate3d(0, 100%, 0).move-enter-active, .move-leave-activetransition: all 0.3 ease-in-out

(3)列表滚动

使用cube-scroll组件实现列表滚动,并且其中添加shop-control组件做商品的购买。

Data中添加visiable控制显示。提供两个方法show() hide()修改visiablemaskClick()方法控制其蒙层隐藏

(4)组件的使用

定义props有select Foods,从而使购物车中选择的商品通过props传递到shop-cart-list组件,

组件使用:将其变成API组件。 在register.js中修改,之后就可以通过API的方式调用。

import ShopCartList from 'components/shop-cart-list/shop-cart-list'
createAPI(Vue, ShopCartList)

(5)添加弹出触发方法

当我们点击底部购物车时会显示这个组件。在shop-cart的content中添加一个点击事件toggleList,并添加该方法。

(添加辅助变量listfold默认为收起状态)在函数中,只有是收起状态才会展开,并且判断商品件数是否为0,不为零显示lsit(_showShopCartList),为零隐藏list(_hidwShopCartList)

toggleList() {if (this.listFold) {if (!this.totalCount) {return}this.listFold = falsethis._showShopCartList()this._showShopCartSticky()} else {this.listFold = truethis._hideShopCartList()}},

并且实现这两个私有方法,使用api调用组件(由于每次都是单例,因此做缓存)

_showShopCartList() {this.shopCartListComp = this.shopCartListComp || this.$createShopCartList({$props: {selectFoods: 'selectFoods'},$events: {hide: () => {this.listFold = true},leave: () => {this._hideShopCartSticky()},add: (el) => {this.shopCartStickyComp.drop(el)}}})this.shopCartListComp.show()},_hideShopCartList() {const comp = this.sticky ? this.$parent.list : this.shopCartListCompcomp.hide && comp.hide()},

(6)存在的问题

但是有个问题就是,shop-cart-list是API组件,会动态的向body中挂载结点,因此层级较高,高过内层组件层级。但是购物车组件是一个子组件,因此会遮盖到原来的购物车组件。但是无法调整层级,

因此解决方法就是:使用shop-cart-sticky组件。动态向body中挂载一个购物车组件的副本。 shop-cart-sticky组件。

(7)商品购买时小球飞入动画

购物车小球,在shop-cat-list的cart-control点击需要向其父组件shop-cart组件派发onAdd()方法

<div class="cart-control-wrapper"><cart-control @add="onAdd" :food="food"></cart-control>
</div>onAdd(target) {this.$emit(EVENT_ADD, target)},

在shop-cart组件中监听该事件,在add中调用shop-cart-sticky组件的drop()方法,(其中需要在shop-cart-sticky中添加drop方法,并调用shop-cart的drop方法。)

_showShopCartList() {this.shopCartListComp = this.shopCartListComp || this.$createShopCartList({$props: {selectFoods: 'selectFoods'},$events: {hide: () => {this.listFold = true},leave: () => {this._hideShopCartSticky()},add: (el) => {this.shopCartStickyComp.drop(el)}}})this.shopCartListComp.show()},

(8)清空购物车

点击清空按钮,添加click事件empty(), 调用cube-ui的dialog,遍历food将所有的count设置为0

empty() {this.$createDialog({type: 'confirm',content: '确认清空购物车吗?',$events: {confirm: () => {this.selectFoods.forEach((food) => {food.count = 0})this.hide()}}}).show()}
}

当商品数量为0时,也要收回list,因此在shop-cart组件中添加watch,对于totalcount,当展开情况,并且值为0,将其关闭。

watch: {fold(newVal) {this.listFold = newVal},totalCount(newVal) {if (!this.listFold && !newVal) {this._hideShopCartList()}}},

(9)结算按钮

对于去结算按钮,添加点击事件pay(),使用cube-ui提供的dialog,当价格大于起送价,计算价格并显示

pay(e) {if (this.totalPrice < this.minPrice) {return}this.$createDialog({title: '支付',content: `您需要支付${this.totalPrice}元`}).show()e.stopPropagation()},

(10)公共部分mixin抽离

所有我们使用的弹层组件都包含了show() hide() 主要用途是修改visible的true false,因此可以抽象出这部分代码,在common中添加mixins文件夹popup.js,在shop-cart-list等中添加引用mixin:[popupMixin]

const EVENT_SHOW = 'show'
const EVENT_HIDE = 'hide'export default {data() {return {visible: false}},methods: {show() {this.visible = truethis.$emit(EVENT_SHOW)},hide() {this.visible = falsethis.$emit(EVENT_HIDE)}}
}

(11)滑动页面购物车关联

对于滑动页面也可以实现购物车的联动问题:在tab组件中我们定义了一个onChange()方法

onChange(current) {this.index = currentconst component = this.$refs.component[current]component.fetch && component.fetch()},

其中会执行组件的fetch方法,在goods组件中定义了这样一个fetch方法,每次都会getGoods,因此添加一个标记,只有当没有定义过时才会getGoods,如果已经获取过一次时就不用再次获取了。

fetch() {if (!this.fetched) {this.fetched = truegetGoods().then((goods) => {this.goods = goods})}},

二、购物车详情shopcart-list区块(一期)

1. 概述

一期实现没有很复杂的部分就是需要添加计算属性listShow,判断totalCount没有商品时将fold = true,否则为true。点击触发togglelist方法控制该部分显示。

2. 布局

组件部分没有抽离出来,而是直接在shop-cart组件中写入,放在整个组件的最下部。

<div class="shopcart-list" v-show="listShow" transition="fold"><div class="list-header"><h1 class="title">购物车</h1><span class="empty" @click="empty">清空</span></div><div class="list-content" v-el:list-content><ul><li class="food" v-for="food in selectFoods"><span class="name">{{food.name}}</span><div class="price"><span>¥{{food.price*food.count}}</span></div><div class="cartcontrol-wrapper"><cartcontrol :food="food"></cartcontrol></div></li></ul></div></div>

3. 实现

(1)实现组件显示隐藏

添加一个fold默认值为true,添加计算属性listShow。判断this.totalCount没有商品fold = true,否则为true。

listShow() {if (!this.totalCount) {this.fold = true;return false;}let show = !this.fold;if (show) {this.$nextTick(() => {if (!this.scroll) {this.scroll = new BScroll(this.$els.listContent, {click: true});} else {this.scroll.refresh();}});}return show;}},

在点击content时触发事件togglelist,并实现方法,当点击list-mask可以收回shop-cart,添加事件listShow事件

toggleList() {if (!this.totalCount) {return;}this.fold = !this.fold;},

(2)实现动画

动画:向上滑动,添加transition=fold,此处点击事件是better-scroll组件派发的事件。

&.fold-transitiontransition: all 0.5stransform: translate3d(0, -100%, 0)&.fold-enter, &.fold-leavetransform: translate3d(0, 0, 0)

(3)蒙层的实现

该组件出现时背后是一个蒙层,因此在shop-cart组件同级下定义list-mask

<div class="list-mask" @click="hideList" v-show="listShow" transition="fade"></div>

并添加渐变效果和样式。模糊效果使用 backdrop-filter: blur(10px)

.list-maskposition: fixedtop: 0left: 0width: 100%height: 100%z-index: 40backdrop-filter: blur(10px)&.fade-transitiontransition: all 0.5sopacity: 1background: rgba(7, 17, 27, 0.6)&.fade-enter, &.fade-leaveopacity: 0background: rgba(7, 17, 27, 0)

三、shop-cart-sticky组件

1. 概括

shop-cart-list是API组件,会动态的向body中挂载结点,因此层级较高,高过内层组件层级。但是购物车组件是一个子组件,因此会遮盖到原来的购物车组件。但是无法调整层级,因此解决方法就是:使用shop-cart-sticky组件。动态向body中挂载一个购物车组件的副本。而Sticky组件就是对chop-cart组件的简单包装。

2. 布局

Sticky组件就是对chop-cart组件的包装,把它需要的数据通过props传入,因此可以把sticky组件作为API调用就可以了。并且也包含hide() show()函数控制visible显隐。

<div class="shop-cart-sticky" v-show="visible"><shop-cartref="shopCart":selectFoods="selectFoods":deliveryPrice="deliveryPrice":minPrice="minPrice":fold="fold":sticky=true></shop-cart></div>

3. 实现

sticky组件要可以跟着页面的切换而保存,因此调用要添加在shop-cart组件的toggleList函数中(如上代码)并实现该私有函数,并接收props

_showShopCartSticky() {this.shopCartStickyComp = this.shopCartStickyComp || this.$createShopCartSticky({$props: {selectFoods: 'selectFoods',deliveryPrice: 'deliveryPrice',minPrice: 'minPrice',fold: 'listFold',list: this.shopCartListComp}})this.shopCartStickyComp.show()},
_hideShopCartSticky() {this.shopCartStickyComp.hide()}

四、createAPI详解

仓库地址:https://github.com/cube-ui/vue-create-api

执行create-api会向vue原型上挂载$createX的方法(如:name:'head-detail' 就会变成$createHeadDetail);

在header组件实例中调用this.createheadDetail而将header看作为其父组件

它的结果是一个组件实例apiComponent,因此就可以调用组件的方法

showDetail() {this.headerDetailComp = this.headerDetailComp || this.$createHeaderDetail({$props: {seller: 'seller'}})this.headerDetailComp.show()  // 调用组件的show方法}

在调用vue.prototype.$createX会做什么事情?

像vue组件生命周期一样,它也有创建,更新和销毁过程。

创建过程:根据传入的参数做一些处理,如processProps。之后就会新建一个vue实例,它的child就是实例组件。在执行vue实例初始化的过程中首先执行init()方法(append to body将组件的DOM添加到body下,这也是它可以动态挂载到body的原因)

更新过程:(如props数据更新)组件会重新渲染,一般使用的组件来说props就是响应式的,一旦改变就会触发组件重新渲染。但是create-api组件会对更新的props进行watch(调用方watch传入的props)当调用方数据发生变化,就会执行回调函数(触发vue的forceupdate,从而使api组件重新渲染)

销毁过程:当调用方销毁,api组件会做相应处理:监听before Destroy钩子函数,当我们api组件的父实例销毁,那么apiComponent 会执行remove方法(清理并执行destroy方法,从而把DOM从body上移除)

整个create-api模块的设计也使用了vue的钩子函数实例方法完成api组件的生命周期

项目总结:vue.js2.5饿了么APP(5)主要组件实现 - 商品详情页部分

项目总结:vue.js2.5饿了么APP(6)主要组件实现 - 评价页+商家页部分

项目总结:vue.js2.5饿了么APP(7)项目部署与总结

项目总结:vue.js2.5饿了么APP(4)主要组件实现 - 购物车相关组件(下)相关推荐

  1. 项目总结:vue.js2.5饿了么APP(1)概述+项目准备

    说明:本总结来源于慕课网 @ustbhuangyi老师的课程<Vue.js2.5+cube-ui重构饿了么App>课程,本博客做了项目总结梳理便于回顾,需要学习的伙伴可以移步学习.与君共勉 ...

  2. 项目总结:vue.js2.5饿了么APP(5)主要组件实现 - 商品详情页部分

    说明:本总结来源于慕课网 @ustbhuangyi老师的课程<Vue.js2.5+cube-ui重构饿了么App>课程,本博客做了项目总结梳理便于回顾,需要学习的伙伴可以移步学习.与君共勉 ...

  3. 项目总结:vue.js2.5饿了么APP(7)项目部署与总结

    说明:本总结来源于慕课网 @ustbhuangyi老师的课程<Vue.js2.5+cube-ui重构饿了么App>课程,本博客做了项目总结梳理便于回顾,需要学习的伙伴可以移步学习.与君共勉 ...

  4. 项目总结:vue.js2.5饿了么APP(3)主要组件实现 - 购物车相关组件(上)

    说明:本总结来源于慕课网 @ustbhuangyi老师的课程<Vue.js2.5+cube-ui重构饿了么App>课程,本博客做了项目总结梳理便于回顾,需要学习的伙伴可以移步学习.与君共勉 ...

  5. 【Vue项目实战】vue.js2.5 饿了么APP(1)概述+项目准备

    一.概述 1. 项目简介 使用vue.js vue是当前最火的MVVM框架,(优点:轻量.简洁.高效.数据驱动.组件化) 本项目做的是:高仿上线外卖APP商家模块 开发过程:需求分析-脚手架工具-数据 ...

  6. vue高仿饿了么APP(二)

    这里我直接跳过vue-cli的安装. 一,vue.js代码是如何运行的? 1,进入页面,首先加载index.html和main.js文件. ① index.html文件 <!DOCTYPE ht ...

  7. vue高仿饿了么APP(三)

    一·需求分析 二,制作css字体图标的制作和使用 前面已经有人做过总结,我就直接引用了 css字体图标的制作和使用. 三,项目目录结构设计 1,每一个组件都单独建立一个文件夹,例如商品页建立goods ...

  8. VUE高仿饿了么app开发思维导图

    来自互联网 文章来源:刘俊涛的博客 地址:http://www.cnblogs.com/lovebing

  9. vue外卖十九:商家详情-底部购物车组件,购物车相关vuex状态设计、相关计算、清空购物车+滚动购物车

    一.购物车基础 1)购物车状态设计cartFoods+mutation store/state.js // 所有要管理的状态数据:从页面需求分析出来,最好和api/index.js里的命名相同 exp ...

最新文章

  1. runtime系统的Cello
  2. 《CDN 之我见》系列二:原理篇(缓存、安全)
  3. 2016_6_27日报
  4. mysql命令导入存储过程报错_mysql导入存储过程时declare报错的有关问题解决
  5. Python学习笔记:Day 16 编写移动App
  6. Html.ActionLink
  7. python中threading产生死锁_什么是死锁,如何避免死锁(4种方法)
  8. PPPOE拨号上网流程及密码窃取具体实现
  9. HTML5 文本元素
  10. 面向站长和网站管理员的Web缓存加速指南[翻译]
  11. 烟台市建筑物矢量数据(Shp格式+带高度)
  12. MATLAB电路仿真搭建教程
  13. 线性代数02 线性方程组的解的情况(矩阵的秩)
  14. matlab贝塔分布,怎么拟合贝塔分布函数
  15. office2019word2019excel2019ppt2019关闭自动更新设置步骤
  16. LaTex常用技巧6:矩阵编写总结
  17. 群晖显示服务器错误代码21,群晖 DSM 6.2.3 升级 25426 错误 21 的解决办法 | 智享阁...
  18. VMware Workstation Pro 转移服务器中的虚拟机
  19. 激光SLAM与视觉SLAM的区别
  20. 两个MATLAB在线工具,画图啥的都不用安装了

热门文章

  1. SpringBoot 整合模板引擎 Thymeleaf 页面跳转失败的解决方案
  2. 一个传统物流企业开发一款专属物流app需要多少成本?
  3. 文档级关系抽取:QIUXP:DORE: Document Ordered Relation Extraction based on Generative Framework
  4. Kicad 导出立创商城标准BOM格式插件---带立创商城元件库---预览(带下载链接)
  5. 三角函数---诱导公式
  6. mysql 5.7 utf8mb4_Mysql 5.7 设置默认urf8mb4
  7. 微机原理与接口技术课程设计——数字电压表的设计(含完整代码与实验连接图)
  8. DM 共享存储集群架构DSC讲解
  9. 从离线分析建模到稳健风控升级,为什么说顶象Dinsight实时风控引擎是对的选择?
  10. MATLAB坐标系变换动画gif(附代码):坐标系旋转动画+坐标系平移动画代码