Vue实现购物车详情页面的方法

上次我们为商品分类菜单添加了显示购物数量,这篇我们继续推进项目,来实现购物车的详情页面,在开始之前我们先看它在页面中的样子:

如上所示,此页面包含了购物列表,而它由商品名称,单价,增减商品功能构成,增减商品功能我们在商品列表中实现过,那么我们现在可以进行复用。

搭出购物车结构

我们将购物车底部构建出来,

<templete>
<div class="shopcart" :class="{'highligh':totalCount>0}">
    <div class="shopcart-wrapper">

    </div>
</div>
</templete>

老情况,在templete模板下的shopcart-wrapper内完成底部购物车一栏:

1 count大于0.让它打开

<!-- 左=>内容包含购物车icon 金额 配送费 -->
      <div class="content-left">
        <div class="logo-wrapper" :class="{'highligh':totalCount>0}" @click="toggleList">
          <span class="icon-shopping_cart logo" :class="{'highligh':totalCount>0}"></span>
          <i class="num" v-show="totalCount">{{totalCount}}</i>
        </div>
        <div class="desc-wrapper">
          <p class="total-price" v-show="totalPrice">¥{{totalPrice}}</p>
          <p class="tip" :class="{'highligh':totalCount>0}">另需{{poiInfo.shipping_fee_tip}}</p>
        </div>
      </div>
      <!-- 去结算 -->
      <div class="content-right" :class="{'highligh':totalCount>0}">
        {{payStr}}
      </div>

搭建所选商品列表

如图所示,我们分好结构,紧接着搭建所选商品的列表

所选商品的列表 shopcart-list默认隐藏的,也就是说我们在没有选择食品的时候,点击购物车它不会展开。

1.list-hearder,左右结构包括1号口袋与清空购物车

2.list-content 列表,存放我们选择的食物

2.1左边是我们的食物名字,商品描述;右侧是数量,加减商品的组件。

<div class="shopcart-list" v-show="listShow" :class="{'show':listShow}">
        <!--列表顶部满减信息-->
        <div class="list-top" v-if="poiInfo.discounts2">
          {{poiInfo.discounts2[0].info}}
        </div>
        <!--1号口袋 清空功能-->
        <div class="list-header">
          <h3 class="title">1号口袋</h3>
          <div class="empty" @click="emptyFn">
            <img src="./ash_bin.png" />
            <span>清空购物车</span>
          </div>
        </div>
        <!--所选商品列表-->
        <div class="list-content" ref='listContent'>
          <ul>
            <li class="food-item" v-for="food in selectFoods">
              <div class="desc-wrapper">
                <!--左侧-->
                <div class="desc-left">
                  <!--所选商品名字-->
                  <p class="name">{{food.name}}</p>
                  <!--所选商品描述 unit 例 des 霆锋苦辣鸡腿堡1个-->
                  <p class="unit" v-show="!food.description">{{food.unit}}</p>
                  <p class="description" v-show="food.description">{{food.description}}</p>
                </div>
                <!--商品单价-->
                <div class="desc-right">
                  <span class="price">¥{{food.min_price}}</span>
                </div>
              </div>
              <!--复用商品增减组件 Cartcontrol-->
              <div class="cartcontrol-wrapper">
                <Cartcontrol :food='food'></Cartcontrol>
              </div>
            </li>
          </ul>
        </div>
        <div class="list-bottom"></div>
      </div>

加入遮罩层

<!-- 遮罩层 -->
    <div class="shopcart-mask" v-show="listShow" @click="hideMask()"></div>

到这里,结构咱们就搭好了。

注册组件,添加功能

我们通过props为购物车组件传入所需要的数据;

计算属性:

  • 通过totalCount计算所选的商品数量;
  • 通过totalPrice计算所选商品的总价;
  • 通过payStr控制去结算;

listShow是我们控制购物车详情页展示的要点,依据totalCount所选商品数量对fold折叠进行控制,fold为true,商品数量为0.购物车详情页为折叠状态。

接着我们将状态取反赋值到show,并且依据show,来控制商品详情页面商品一定多时,可以进行鼠标滚动。

方法:

通过toggleList点击购物车logo时候,进行判断,如果没有选择商品那么我们什么也不做。如果我们选择了商品,那么将fold取反。因为我们在计算属性listShow中设置过实例中的fold属性为true,所有它是折叠的。在我们取反后,它就会展开。

emptyFn清空购物车

最后我们点击遮罩层的时候,让遮罩层隐藏,也就是fold为true。

<script>
  // 导入BScroll
  import BScroll from 'better-scroll'
  // 导入Cartcontrol
  import Cartcontrol from 'components/Cartcontrol/Cartcontrol'

  export default {
    data() {
      return {
        fold: true
      }
    },
    props: {
      poiInfo: {
        type: Object,
        default: {}
      },
      selectFoods: {
        type: Array,
        default() {
          return [
            //            {
            //              min_price: 10,
            //              count: 3
            //            },
            //            {
            //              min_price: 7,
            //              count: 1
            //            }
          ];
        }
      }
    },
    computed: {
      // 总个数
      totalCount() {
        let num = 0;
        this.selectFoods.forEach((food) => {
          num += food.count;
        });

        return num;
      },
      // 总金额
      totalPrice() {
        let total = 0;
        this.selectFoods.forEach((food) => {
          total += food.min_price * food.count;
        });

        return total;
      },
      payStr() {
        if(this.totalCount > 0) {
          return "去结算";
        } else {
          return this.poiInfo.min_price_tip;
        }
      },
      listShow() {
        if(!this.totalCount) { // 个数为0
          this.fold = true;

          return false;
        }

        let show = !this.fold;

        // BScoll相关
        if(show) {
          this.$nextTick(() => {
            if(!this.shopScroll) {
              this.shopScroll = new BScroll(this.$refs.listContent, {
                click: true
              });
            } else {
              this.shopScroll.refresh();
            }
          });
        }

        return show;
      }
    },
    methods: {
      toggleList() {
        if(!this.totalCount) { // 个数为0
          return;
        }
        this.fold = !this.fold;
      },
      emptyFn() {
        this.selectFoods.forEach((food) => {
          food.count = 0;
        });
      },
      hideMask() {
        this.fold = true;
      }
    },
    components: {
      Cartcontrol,
      BScroll
    }
  }
</script>

样式

<style>
.shopcart-wrapper{
  width: 100%;
  height: 51px;
  background: #514f4f;
  position: fixed;
  left: 0;
  bottom: 0;
  display: flex;
  z-index: 99;
}
.shopcart-wrapper.highligh{
  background: #2d2b2a;
}
.shopcart-wrapper .content-left{
  flex: 1;
}
.shopcart-wrapper .content-left .logo-wrapper{
  width: 50px;
  height: 50px;
  background: #666666;
  border-radius: 50%;
  position: relative;
  top: -14px;
  left: 10px;
  text-align: center;
  float: left;
}
.shopcart-wrapper .content-left .logo-wrapper.highligh{
  background: #ffd161;
}
.shopcart-wrapper .content-left .logo-wrapper .logo{
  font-size: 28px;
  color: #c4c4c4;
  line-height: 50px;
}
.shopcart-wrapper .content-left .logo-wrapper .logo.highligh{
  color: #2D2B2A;
}
.shopcart-wrapper .content-left .logo-wrapper .num{
  width: 15px;
  height: 15px;
  line-height: 15px;
  border-radius: 50%;
  font-size: 9px;
  color: white;
  background: red;
  position: absolute;
  right: 0;
  top: 0;
}
.shopcart-wrapper .content-left .desc-wrapper{
  float: left;
  margin-left: 13px;
}
.shopcart-wrapper .content-left .desc-wrapper .total-price{
  font-size: 18px;
  line-height: 33px;
  color: white;
}
.shopcart-wrapper .content-left .desc-wrapper .tip{
  font-size: 12px;
  color: #bab9b9;
  line-height: 51px;
}
.shopcart-wrapper .content-left .desc-wrapper .tip.highligh{
  line-height: 12px;
}
.shopcart-wrapper .content-right{
  flex: 0 0 110px;
  font-size: 15px;
  color: #BAB9B9;
  line-height: 51px;
  text-align: center;
  font-weight: bold;
}
.shopcart-wrapper .content-right.highligh{
  background: #FFD161;
  color: #2D2B2A;
}
.shopcart-wrapper .shopcart-list{
  position: absolute;
  left: 0;
  top: 0;
  z-index: -1;
  width: 100%;
}
.shopcart-wrapper .shopcart-list.show{
  transform: translateY(-100%);
}
.shopcart-wrapper .shopcart-list .list-top{
  height: 30px;
  text-align: center;
  font-size: 11px;
  background: #f3e6c6;
  line-height: 30px;
  color: #646158;
}
.shopcart-wrapper .shopcart-list .list-header{
  height: 30px;
  background: #F4F4F4;
}
.shopcart-wrapper .shopcart-list .list-header .title{
  float: left;
  border-left: 4px solid #53c123;
  padding-left: 6px;
  line-height: 30px;
  font-size: 12px;
}
.shopcart-wrapper .shopcart-list .list-header .empty{
  float: right;
  line-height: 30px;
  margin-right: 10px;
  font-size: 0;
}
.shopcart-wrapper .shopcart-list .list-header .empty img{
  height: 14px;
  margin-right: 9px;
  vertical-align: middle;
}
.shopcart-wrapper .shopcart-list .list-header .empty span{
  font-size: 12px;
  vertical-align: middle;
}
.shopcart-wrapper .shopcart-list .list-content{
  max-height: 360px;
  overflow: hidden;
  background: white;
}
.shopcart-wrapper .shopcart-list .list-content .food-item{
  height: 38px;
  padding: 12px 12px 10px 12px;
  border-bottom: 1px solid #F4F4F4;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper{
  float: left;
  width: 240px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-left{
  float: left;
  width: 170px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-left .name{
  font-size: 16px;
  margin-bottom: 8px;
  /* 超出部分隐藏*/
  -webkit-line-clamp: 1;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  height: 16px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-left .unit{
  font-size: 12px;
  color: #B4B4B4;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-left .description{
  font-size: 12px;
  color: #B4B4B4;
  /* 超出部分隐藏*/
  overflow: hidden;
  height: 12px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-right{
  float: right;
  width: 70px;
  text-align: right;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .desc-wrapper .desc-right .price{
  font-size: 12px;
  line-height: 38px;
}
.shopcart-wrapper .shopcart-list .list-content .food-item .cartcontrol-wrapper{
  float: right;
  margin-top: 6px;
}
.shopcart .shopcart-mask{
  position: fixed;
  top: 0;
  right: 0;
  width: 100%;
  height: 100%;
  z-index: 98;
  background: rgba(7,17,27,0.6);
}
</style>

总结

我们从搭购物车结构,到所选商品列表细化,这里我们复用了增减商品的组件,然后加入遮罩层。通过计算属性与方法,加入控制逻辑完成了购物车的详情页面。

以上所述实小编给大家介绍的Vue实现购物车详情页面的方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

时间: 2019-08-17

vue.js购物车添加商品组件的方法

现实向购物车添加商品组件 代码 <template> <div class="cartcontrol"> <!--商品减一区域--> <div class="reduce" v-show="food.count>0"> <i class="icon-remove_circle_outline"></i> </div> <!--商品数

Vue实现购物车的全选、单选、显示商品价格代码实例

今天中午废了一会时间,总算把项目中的购物车的单选.全选.以及实现数据的动态显示做出来了,给小白分享一下我个人一个解决办法: 购物车的基本页面如下: 先说实现的总体思路 1.给table表中表头th加一个 checkbox,设这两个事件:@click="checkAll" v-model="checkall": 2.给对应的tr加一个 checkbox 绑定一个事件 v-model="checked",checked设为数组,专门放商品Id: 3.

vue 实现购物车总价计算

效果如下所示: js <script type="text/javascript"> window.οnlοad=function () { var vm = new Vue({ el:'#huo', data:{ myList:[ { number:0, price:23 }, { number:0, price:14.5 }, { number:1, price:8 }, { number:0, price:20 } ], total:0, //总价 bestValue

vue框架制作购物车小球动画效果实例代码

最近在学习前端制作了一个购物车小球的动画效果 直接上图看看效果 下面介绍一下制作这个动画的详细过程: 1.因为使用vue锁业需要使用transition标签包裹 并指定动画三个动画生命周期函数 <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"> <div class="ball" v-if=&quo

Vue商品控件与购物车联动效果的实例代码

本篇我们将构建商品控件与购物车联动. 商品控件 商品控件的结构编写 在商品组件的<template>标签内完成项目结构,以及数据,事件的绑定,与判断逻辑的书写. <template> <div class="goods"> <div class="menu-wrapper" ref="menuScroll"> <ul> <!--专场--> <li class="

vue+vant-UI框架实现购物车的复选框全选和反选功能

购物车页面的设计图 商品的列表 代码: <ul v-if="shoppingListData.rows.length"> <li v-for="(item,index) in shoppingListData.rows" :key="index" > <van-checkbox :value="item.goods_id" v-model="item.isChecked" ch

vue实现购物车小案例

本文实例为大家分享了vue实现购物车小案例的具体代码,供大家参考,具体内容如下 最终效果 HTML部分: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>shopcar.html</title> <script src="https://cdn.jsdelivr.net/npm/vue&q

JS库中的Particles.js在vue上的运用案例分析

知乎的首页后面的粒子动效总觉得很炫酷,搜了一下,发现是用particles.js编写的.刚好目前的项目是利用vue框架的,两个凑在一起学了. 讲道理,这个用得好的话,页面是可以很酷的,譬如我现在写的项目 酷酷的登录页 嘻嘻~ 安装particles.js npm install --save particles.js 配置particles.js 1.data 这个data是用于控制粒子在页面中所呈现的状态. { "particles": { "number": {

Android组件WebView编写有道词典小案例分享

最近学习了WebView组件,写了一个有道词典的小案例,分享给大家,供大家参考,具体内容如下 效果图: 源码下载:https://coding.net/u/gxs1225/p/YouDaoDictionary/git 代码如下: 布局 activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schema

AngularJS tab栏实现和mvc小案例实例详解

tab栏: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Tab 标签</title> <style> body { margin: 0; padding: 0; background-color: #F7F7F7; } .tabs { width: 400px; margin: 3

JSP+MySQL实现网站的登录与注册小案例

为了练手,我就自己试着做了一个网站的登录与注册的小案例.由于没有做美化处理,所以界面并不是很好看. 网站实现的功能如下:  •用户首次注册功能  •用户登录功能 下面我将会分模块展示 注册模块 首先需要一个注册界面,如下register.jsp: <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOC

省市二级联动小案例讲解

在网页开发过程中,选择省市的时候,省市之间有关联,这是一个小小的二级联动案例 ,运用到HTML.css.php.js以及 AJAX的异步请求 首先建立city.php和province.php文件和connet.html,将二级联动的大概结构写出来,html代码如下: <label>省份:</label> <select id="province"> <option>请选择</option> </select> &