欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

非node环境下的vue.js 实现简单的购物车计算功能 样式请无视

程序员文章站 2022-03-13 11:15:54
都说vue的双向数据绑定好用,自己用了下,感觉做购物车没想象中好用。自己的实现如下: 闲来无事,使用非node环境的vue,写一些功能,vue主要是数据的变化,个人感觉是这样,第一次写微博,难免疏漏,请谅解。 本人试过直接,把checkbox的value和text的value直接绑定,数量为空时会有 ......

都说vue的双向数据绑定好用,自己用了下,感觉做购物车没想象中好用。自己的实现如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
    <script src="js/axios.min.js"></script>
</head>
<body>
<div id="app">
    <input type="checkbox" v-model="checkedAll">
    <ul>
        <li v-for="(item,index) in shopingcart">
            <input type="checkbox" v-model="checkedNames[index]"><img
                :src="item.imgUrl"
                alt="">
            <div><span class="price">¥{{item.unitPrice}}</span></div>
            <div class="item-amount "><a href="#" class="J_Minus no-minus" @click="minus(index)">-</a><input
                    @change="num(event,index)"
                    type="text"
                    v-model="item.quantity"
                    class="text text-amount J_ItemAmount"
                    autocomplete="off"><a href="#"
                                          class="J_Plus plus"
                                          @click="add(index)">+</a>
            </div>
            <div class="td-inner"><em tabindex="0" class="J_ItemSum number">¥{{Math.ceil(parseFloat(item.unitPrice*item.quantity)*10)/10}}</em>
                <div class="J_ItemLottery"></div>
                <div class="weight" data-spm-anchor-id="a1z0d.6639537.1997196601.i2.4cf574843pYndQ">
                    ({{Math.ceil(parseFloat(item.weight*item.quantity)*100)/100}}kg)
                </div>
            </div>
        </li>
    </ul>
    <span>Checked names: {{ checkedNames }}</span>
    <input type="checkbox" v-model="checkedAll"> <span>{{goodTotal}}</span>件 合计:<span>{{priceAll}}</span> 结算
</div>
<script>
    var Data = {
        test: [
            {
                imgUrl: 'https://img.alicdn.com/bao/uploaded/i2/725677994/TB1Z1mzXMmTBuNjy1XbXXaMrVXa_!!0-item_pic.jpg_80x80.jpg',
                unitPrice: 29.90,
                weight: 0.2,
                detail: '百草味 黄桃干100g*2 零食蜜饯水果干 杏果果脯杏脯',
                quantity: 1
            },
            {
                imgUrl: 'https://img.alicdn.com/bao/uploaded/i2/725677994/TB1Z1mzXMmTBuNjy1XbXXaMrVXa_!!0-item_pic.jpg_80x80.jpg',
                unitPrice: 19.90,
                weight: 0.15,
                detail: '百草味 黄桃干100g*2 零食蜜饯水果干 杏果果脯杏脯',
                quantity: 1
            },
            {
                imgUrl: 'https://img.alicdn.com/bao/uploaded/i2/725677994/TB1Z1mzXMmTBuNjy1XbXXaMrVXa_!!0-item_pic.jpg_80x80.jpg',
                unitPrice: 9.90,
                weight: 0.31,
                detail: '百草味 黄桃干100g*2 零食蜜饯水果干 杏果果脯杏脯',
                quantity: 1
            }
        ]
    }
    var app = new Vue({
        el: '#app',
        data: {
            goodTotal: 0,
            priceAll: 0,
            checkedAll: false,
            shopingcart: Data.test,
            checkedNames: []
        },
        methods: {
            add: function (index) {
                this.shopingcart[index].quantity++;
                console.log(this.shopingcart[index].quantity);
                // 如果checkedNames存在,即是选中
                if (this.checkedNames.length > 0) {
                    this.recalculation(this.checkedNames);
                }
            },
            num: function (event, index) {
                if (event.target.value <= 0) {
                    return false
                }
                var obj = event.target;
                this.shopingcart[index].quantity = event.target.value;
                // 如果checkedNames存在,即是选中
                if (this.checkedNames.length > 0) {
                    this.recalculation(this.checkedNames);
                }
            },
            minus: function (index) {
                if (this.shopingcart[index].quantity <= 1) {
                    return false
                }
                this.shopingcart[index].quantity--;
                // 如果checkedNames存在,即是选中
                if (this.checkedNames.length > 0) {
                    this.recalculation(this.checkedNames);
                }
            },
            checkAll: function () {
                if (!this.checkAll) {
                    this.checkAll = !this.checkAll;
                }
            },
            recalculation: function (newVal) {
                var _this = this,
                    Total = 0,
                    priceAll = 0;
                // 获取总数total和合计元
                newVal.forEach(function (item, index) {
                    if (item == true) {
                        Total += parseInt(_this.shopingcart[index].quantity);
                        priceAll += _this.shopingcart[index].unitPrice * _this.shopingcart[index].quantity;
                    }
                })
                this.goodTotal = Total;
                this.priceAll = Math.ceil(parseFloat(priceAll) * 100) / 100;
            }
        },
        watch: {
            checkedNames: function (newVal) {
                console.log(newVal)
                // 选项发生变化,重新计算价格
                this.recalculation(newVal);
            },
            checkedAll: function (Val) {
                var _this = this;
                if (!Val) {
                    _this.checkedNames = []
                    return false;
                }
                // 先置为空,保证checkedNames发生变化
                _this.checkedNames = []
                this.shopingcart.forEach(function (item, index) {
                    // _this.checkedNames[index] = true  此处有bug,为何?
                    _this.checkedNames.push(true)
                })
            }
        }
    })
    /*
    *  受现代js的限制,vue不能检测到对象属性的添加或删除。
    *  由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的
    * */
</script>
</body>
</html>

 

闲来无事,使用非node环境的vue,写一些功能,vue主要是数据的变化,个人感觉是这样,第一次写微博,难免疏漏,请谅解。

本人试过直接,把checkbox的value和text的value直接绑定,数量为空时会有true和false出现,所以用checkedNames数组的形式控制多个input值,数据变化参考最下方span标签。

这里还有个坑就是受现代js的限制,vue不能检测到对象属性的添加或删除。

本例子没使用es6箭头函数,因此使用_this获取vue对象。

本例子通过监听checkedNames的变化,每次重新计算所有商品的数量变化,从而实现所有商品价格的计算,有些地方感觉有bug,但是没弄懂,希望大家一起探讨