美文网首页
vue + iview 实现购物车功能

vue + iview 实现购物车功能

作者: 清风鹿野 | 来源:发表于2018-07-14 22:48 被阅读0次
image.png
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name ="viewport" content ="width = device-width,initial-scale = 1.0,user-scalable = no"/>
    <title>shopcart</title>
    <link rel="stylesheet" type="text/css" href="static/css/iview.css">
    <script type="text/javascript" src="static/js/vue.js"></script>
    <script type="text/javascript" src="static/js/iview.min.js"></script>
    <style>
        * {
            padding: 0;
            margin: 0;
            list-style: none;
        }
        header {
            height: 42px;
            width: 100%;
            position: fixed;
            top: 0;
            left: 0;
            background: #fff;
            box-shadow: 0px 0px 20px rgba(0, 0, 0, .1);
            font-size: 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            z-index: 10;
        }
        header span {
            font-size: 14px;
            font-weight: bold;
        }
        footer {
            height: 42px;
            width: 100%;
            position: fixed;
            bottom: 0;
            left: 0;
            background: #fff;
            box-shadow: 0px 0px 20px rgba(0, 0, 0, .1);
        }
        footer ul {
            display: flex;
            flex-direction: row;
            justify-content: space-around;
        }
        footer ul li {
            line-height: 42px;
            text-align: center;
            font-weight: bold;
            font-size: 24px;
            height: 42px;
        }
        footer ul li:nth-child(3) {
            position: relative;
        }
        .num-badge {
            position: absolute;
            top: 0;
            font-weight: normal;
            display: block;
            background: #ed3f14;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            font-size: 9px;
            right: -10px;
            overflow: hidden;
            line-height: 20px;
            text-align: center;
            color: #fff;
        }
        .container {
            margin-top: 42px;
            margin-bottom: 42px;
        }
        .goods-list {
            padding: 8px;
        }
        .goods {
            display: flex;
            padding-top: 10px;
            flex-direction: row;
            justify-content: space-between;
            padding-bottom: 10px;
            position: relative;
        }
        .goods:after {
            content: ' ';
            position: absolute;
            bottom: 0;
            display: block;
            width: 200%;
            left: -50%;
            height: 1px;
            background: #ededed;
            -webkit-transform:scale(0.5);
        }
        .goods img {
            height: 64px;
            width: 64px;
            border-radius: 2px;
        }
        .goods-title {
            font-weight: bolder;
            font-size: 13px;
        }
        .goods-content {
            display: flex;
            flex-direction: column;
            justify-content: space-around;
            flex: 1;
            margin-left: 10px;
        }
        .goods-desc {
            font-size: 9px;
            text-overflow: ellipsis;
            white-space: nowrap;
            overflow: hidden;
            width: 150px;
        }
        .goods-price {
            color: red;
        }
        .cart-controller {
            display: flex;
            flex-direction: row;
            align-items: center;
        }
        .cart-controller span{
            margin-right: 5px;
        }
        .reduce,.add {
            font-size: 18px;
            color: #2d8cf0;
        }
        .goods-num {
            width: 12px;
            text-align: center;
        }
        .cart-bar {
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            height: 42px;
            width: 100%;
            background: #fff;
            align-items: center;
            padding: 5px;
            position: fixed;
            top: 0;
            left: 0;
            z-index: 11;           
        }
        .pay-btn {
            width: 70px;
        }
        .total-price {
            text-align: center;
            flex: 1;
            font-size: 13px;
            color: red;
        }
        .total-price span {
            color: #222;
            font-size: 18px;
            font-weight: bolder;
        }
        .num-badge.gray {
            background: #ccc;
        }
        .slide-fade-enter-active {
          transition: all .1s ease;
        }
        .slide-fade-leave-active {
          transition: all .3s cubic-bezier(1.0, 0.5, 0.8, 1.0);
        }
        .slide-fade-enter, .slide-fade-leave-to {
          transform: translateX(10px);
          opacity: 0;
        }
    </style>
</head>
<body>
    <div id="app">
        <header>
             <Icon type="ios-list" style="margin-left:10px;"></Icon>
             <span>{{pageHead}}</span>
             <Icon type="ios-search" style="margin-right:10px;"></Icon>     
        </header>
        <div class="container">
            <ul class="goods-list">
                                <!-- css3 动画名称 -->
                <transition name="slide-fade" v-for="(goods,index) in goodsList">
                    <li class="goods"  v-if="goods.goods_num">
                        <img :src="goods.goods_thumb" alt="">
                        <div class="goods-content">
                            <p class="goods-title">{{goods.goods_name}}</p>
                            <p class="goods-desc">{{goods.goods_desc}}</p>
                            <p class="goods-price">¥{{goods.goods_price}}</p>
                        </div>
                        <div class="cart-controller">
                            <span class="reduce"  @click="reduceGoods(index)">
                                <Icon type="minus-circled"></Icon>
                            </span>
                            <span class="goods-num">{{goods.goods_num}}</span>
                            <span class="add" @click="addGoods(index)">
                                <Icon type="plus-circled"></Icon>
                            </span>
                        </div>
                    </li>
                </transition>
            </ul>
            <div class="cart-bar">
                <div class="total-price">
                    <span>Total:</span> ¥{{totalPrice}}
                </div>
                <i-button type="success" class="pay-btn" @click="pay(totalPrice)">支付</i-button>    
            </div>
        </div>
        <Modal v-model="modal6" title="提示"  @on-ok="ok" @on-cancel="cancel">
        <p>总价:¥{{totalPrice}}</p>
    </Modal>
        <footer>
            <ul>
                <li>
                    <Icon type="ios-home"></Icon>
                </li>
                <li>
                    <Icon type="ios-chatbubble"></Icon>
                </li>
                <li>
                    <Icon type="ios-cart"></Icon>
                                                            <!--  绑定样式,isGray为true时显示  -->
                    <span class="num-badge"  v-bind:class="{gray:isGray}">{{goodsNum}}</span>
                </li>
                <li>
                    <Icon type="ios-person"></Icon>
                </li>
            </ul>
        </footer>
    </div>
<script>
    new Vue({
        el: '#app',
        data: {
            isGray: false,//默认false
            modal6: false,
            pageHead: "购物车",
            goodsList: [
                {
                    goods_name: "Coca Cola",
                    goods_desc: "可口可乐,made in America",
                    goods_price: "12",
                    goods_thumb: "static/images/cola.jpg",
                    goods_num: 6
                },{
                    goods_name: "女装",
                    goods_desc: "夏日女装",
                    goods_price: "199",
                    goods_thumb: "static/images/clothfamale.jpg",
                    goods_num: 1
                },{
                    goods_name: "macbook 13寸 经典版",
                    goods_desc: "macbook 13寸 经典版,限时打折",
                    goods_price: "6999",
                    goods_thumb: "static/images/mac.jpg",
                    goods_num: 1
                },{
                    goods_name: "青芒果",
                    goods_desc: "深山青芒果",
                    goods_price: "6",
                    goods_thumb: "static/images/mongo.jpg",
                    goods_num: 5
                },{
                    goods_name: "play station 4",
                    goods_desc: "索尼正品认证,限时赠送<<神秘海域4>>",
                    goods_price: "2666",
                    goods_thumb: "static/images/ps4.jpg",
                    goods_num: 1
                },{
                    goods_name: "纯正米酒",
                    goods_desc: "哇哦~~",
                    goods_price: "99",
                    goods_thumb: "static/images/ricewine.jpg",
                    goods_num: 3
                },
            ]
        },
        computed: {
            totalPrice: function(){//计算总价
                var total = 0;
                this.goodsList.forEach(function(item,index){//循环商品列表,单价 x 数量,再加等
                    total += (item.goods_price - 0) * item.goods_num;
                });
                return total
            },
            goodsNum: function(){//加等每个商品种类的数量 
                var num = 0;
                this.goodsList.forEach(function(item,index){
                    num += item.goods_num;
                });
                if(num == 0) {//如果商品总量为0时,this.isGray = true
                    this.isGray = true
                }
                return num
            }
        },
        methods: {
            //v-for="(goods,index) in goodsList" 通过这种方式获取index
            addGoods: function(index){//@click(index),在商品列表数组中传入点击商品的index值,从而改变相应商品的数据
                this.goodsList[index].goods_num ++ ;
            },
            reduceGoods: function(index){//@click(index),在商品列表数组中传入点击商品的index值,从而改变相应商品的数据
                if(this.goodsList[index].goods_num <= 0) {//当商品数量小于或等于0时,利用vue的transition组件包裹单个goods li,做到动画消失
                    this.goodsList.splice(index,1);//也可以在goods----li 标签里利用v-if或者 v-bind:class="{your-animate-class:goods.goods_num}"方式
                    return                         //完全消失后在商品列表中移除该商品         
                }
                this.goodsList[index].goods_num -- ;
            },
            pay: function(){
                this.modal6 = true;//ivew 对话框组件,点击支付显示
            },
            ok: function(){//点击确定,关闭
                    this.modal6 = false;
                    this.$Message.success('支付成功');//iview 消息提示组件
            },
            cancel: function(){
                this.modal6 = false;
                this.$Message.success('取消支付');
            }
        }  
    })
    /**
    * 总结
    * v-bind:class="{classname: variable<-->boolean}"
    * @click="functionname()"绑定函数
    * computed: 计算属性的运用; totalPrice,goodsNum
    * splice(item,0,[]) => 0:增加item或者[]; 1: 删除item
    * v-for="(item,index) in items" => item = self,index = self index
    * v-if="variable" => true or false
    * vue组件transition的运用 naem="animation-name" v-if状态的改变触发动画
    * iview 组件Icon的使用,badge的使用(其中count属性不支持,count="{{ goodsNum }}"的形式 => 也许有解决方案,不行可以自行模拟)
    * iview 组件this.$Message.success(msg)
    *                       .info(msg)
    *                       .error(msg) 
    * iview 组件<Modal v-modal="modalvalue" :loading="loading" @on-ok="ok" @on-cancel="cancel"></Modal> ==> 通过设置modalvalue的值来显隐modal对话框
    * :loading => 是否在确定按钮上使用 loading 动画 title => 设置标题信息 @on-ok="ok" => 点击确定按钮回调函数 @on-cancel="cancel" => 点击取消按钮回调函数
    *  
    * date: 2018-7-14 22:46
    * author: Foresea
    *
    *
    * =====================  待续  =====================       
    */
  </script>
</body>
</html>

相关文章

网友评论

      本文标题:vue + iview 实现购物车功能

      本文链接:https://www.haomeiwen.com/subject/hhdupftx.html