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


Posted in Javascript onAugust 20, 2019

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

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>

搭建所选商品列表

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

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

所选商品的列表 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实现购物车详情页面的方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
50个比较实用jQuery代码段
Sep 18 Javascript
JS HTML5 音乐天气播放器(Ajax获取天气信息)
May 26 Javascript
使用不同的方法结合/合并两个JS数组
Sep 18 Javascript
javascript实现ecshop搜索框键盘上下键切换控制
Mar 18 Javascript
JS实现当前页居中分页效果的方法
Jun 18 Javascript
jquery动感漂浮导航菜单代码分享
Apr 15 Javascript
整理关于Bootstrap过渡动画的慕课笔记
Mar 29 Javascript
vue深入解析之render function code详解
Jul 18 Javascript
小程序组件之仿微信通讯录的实现代码
Sep 12 Javascript
jQuery控制input只能输入数字和两位小数的方法
May 16 jQuery
vue 使用post/get 下载导出文件操作
Aug 07 Javascript
DWR内存兼容及无法调用问题解决方案
Oct 16 Javascript
详解解决小程序中webview页面多层history返回问题
Aug 20 #Javascript
JavaScript使用表单元素验证表单的示例代码
Aug 20 #Javascript
vue悬浮可拖拽悬浮按钮的实例代码
Aug 20 #Javascript
JS中的算法与数据结构之链表(Linked-list)实例详解
Aug 20 #Javascript
使用 webpack 插件自动生成 vue 路由文件的方法
Aug 20 #Javascript
微信小程序webview与h5通过postMessage实现实时通讯的实现
Aug 20 #Javascript
JS中的算法与数据结构之队列(Queue)实例详解
Aug 20 #Javascript
You might like
如何修改和添加Apache的默认站点目录
2013/07/05 PHP
PHP防止表单重复提交的几种常用方法汇总
2014/08/19 PHP
php中switch语句用法详解
2015/08/17 PHP
php获取当前月与上个月月初及月末时间戳的方法
2016/12/05 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
Javascript 实现的数独解题算法网页实例
2013/10/15 Javascript
让jQuery Mobile不显示讨厌loading界面的方法
2014/02/19 Javascript
ie9 提示'console' 未定义问题的解决方法
2014/03/20 Javascript
jQuery源码解读之hasClass()方法分析
2015/02/20 Javascript
JavaScript实现算术平方根算法-代码超简单
2015/09/11 Javascript
Ionic+AngularJS实现登录和注册带验证功能
2017/02/09 Javascript
用Nodejs搭建服务器访问html、css、JS等静态资源文件
2017/04/28 NodeJs
webpack打包单页面如何引用的js
2017/06/07 Javascript
webpack配置sass模块的加载的方法
2017/07/30 Javascript
微信上传视频文件提示(推荐)
2018/11/22 Javascript
layer.js之回调销毁对话框的例子
2019/09/11 Javascript
vue-openlayers实现地图坐标弹框效果
2020/09/24 Javascript
python写入中英文字符串到文件的方法
2015/05/06 Python
python遍历目录的方法小结
2016/04/28 Python
Python实现PS滤镜Fish lens图像扭曲效果示例
2018/01/29 Python
opencv与numpy的图像基本操作
2019/03/08 Python
Python计算两个矩形重合面积代码实例
2019/09/16 Python
简述python&amp;pytorch 随机种子的实现
2020/10/07 Python
Python爬虫如何破解JS加密的Cookie
2020/11/19 Python
利用纯html5绘制出来的一款非常漂亮的时钟
2015/01/04 HTML / CSS
小橄榄树:Le Petit Olivier
2018/04/23 全球购物
光电信息专业应届生求职信
2013/10/07 职场文书
简历中个人自我评价范文
2013/12/26 职场文书
证婚人搞笑证婚词
2014/01/10 职场文书
合作协议书
2014/04/23 职场文书
初三学生语文考试作弊检讨书
2014/12/14 职场文书
幼儿园推普周活动总结
2015/05/07 职场文书
魂断蓝桥观后感
2015/06/10 职场文书
golang日志包logger的用法详解
2021/05/05 Golang
Python中for后接else的语法使用
2021/05/18 Python
js面向对象编程OOP及函数式编程FP区别
2022/07/07 Javascript