使用 Vue.js 开发一个购物车结算模块

imPony 发布于:2017-11-24 10:42:40

前言


经过近四年的发展,Vue.js 这个尤雨溪一个人开发的框架几乎可以和 Facebook 一个团队开发的 React 抗衡。

Vue.js 对大家来说是个新东西,也是非常重要的东西,它和 jQuery 编程是完全不同的思路,是目前 Web 应用的主流开发框架。



互动:

  1. 解释什么是状态

  2. 询问大家购物车应该具备哪些功能?对于 Vue 第一感觉是什么?



第一步


要点:思考业务逻辑,设计 HTML 结构


<div id="app" class="wp">
    <h1>购物车</h1>
    <ol>
        <li>
            <button>X</button>
            <input type="number"
                   min="0"
                   max=“0"
                   value=“0” />
            <em>¥0</em>
            商品 SKU 名
        </li>
    </ol>
    <p>总计:¥0</p>
</div>



互动:思考数据应该怎么组织,哪些数据是变量,哪些是需要实时更新的变量?



第二步


要点:

  1. v-bind、v-model

  2. {{ 变量、表达式 }}

  3. new Vue() 数据


<div id="app" class="wp">
    <h1>购物车</h1>
    <ol>
        <li v-for="item in sku">
            <button>X</button>
            <input type="number"
                   min="0"
                   v-bind:max="item.stock"
                   v-model:value=“item.count" />
            <em>¥{{ item.price }}</em>
            {{ item.name }}
        </li>
    </ol>
    <p>总计:¥0</p>
</div>
...
var cart = new Vue({
    el: "#app",
    data: {
        sku: [
            {
                name: "iPhone X 64GB Black",
                price: 8388,
                count: 1,
                stock: 5
            },
            {
                name: "iPhone 8 Plus 256GB Gold",
                price: 6388,
                count: 2,
                stock: 50
            },
            {
                name: "小米电视4 55寸",
                price: 4499,
                count: 1,
                stock: 2
            },
            {
                name: "小米电视4A 32寸",
                price: 999,
                count: 1,
                stock: 50
            },
        ]
    }
});



互动:应该如何来组织行为?



第三步


要点:

  1. v-bind、v-on

  2. v-on 时执行的方法

  3. methods、computed


    <button v-on:click="deleteItem(item)">X</button>
    ...
            <input type="number"
                   min="0"
                   v-bind:max="item.stock"
                   v-model:value="item.count"
                   v-on:input="outOfStock(item)" />
    ...
    <p>总计:¥{{ totalPrice }}</p>
    ...
        lang: {
            cantLessThanZero: '值不能小于 0!',
            outOfStock: '没有那么多库存了!'
        }
    ...
    methods: {
        outOfStock: function (item) {
            if(item.count < 0) {
                item.count = 0;
                alert(this.lang.cantLessThanZero);
            }
            if(item.count > item.stock) {
                item.count = item.stock;
                alert(this.lang.outOfStock);
            }
        },
        deleteItem: function (item) {
            var _sku = this.sku;
            var index = _sku.indexOf(item);
            _sku.splice(index, 1);
        }
    },
    computed: {
        totalPrice: function () {
            var sum = 0;
            this.sku.forEach(function (o) {
                sum += o.price * o.count;
            });
            return sum;
        }
    }


实例


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>使用 Vue.js 开发一个购物车结算模块</title>
<style>
html, body, h1, h2, p, ol, li { margin: 0; padding: 0; text-align: center; }
body, input, button { font: 16px/1.5 sans-serif; outline: none; }
input { padding: 5px 10px; width: 40px; }
.wp { margin: 50px auto; max-width: 480px; border: 1px solid #ccc; }
li { overflow: hidden; padding: 15px; line-height: 2.4; border-bottom: 1px solid #ddd; text-align: left; }
    li:first-child { border-top: 1px solid #ddd; }
    li > em, li > input, li > button { float: right; }
    li > input { margin: 0 15px;  }
    li > button { height: 38px; background: transparent; border: none; }
p { font-size: 24px; }
h1, h2, p { margin: 20px 0; }
[v-cloak] { display: none; }
</style>
<script src="https://cdn.bootcss.com/vue/2.5.3/vue.min.js"></script>
</head>
<body>
<div id="app" class="wp" v-cloak>
    <h1>购物车</h1>
    <ol>
        <li v-for="item in sku">
            <button v-on:click="deleteItem(item)">X</button>
            <input type="number"
                   min="0"
                   v-bind:max="item.stock"  
                   v-model:value="item.count"
                   v-on:input="outOfStock(item)" />
            <em>¥{{ item.price }}</em>
            {{ item.name }}
        </li>
    </ol>
    <p>总计:¥{{ totalPrice }}</p>
</div>
<script>
var cart = new Vue({
    el: "#app",
    data: {
        sku: [
            {
                id: 1,
                name: "iPhone X 64GB Black",
                price: 8388,
                count: 1,
                stock: 5
            },
            {
                id: 2,
                name: "iPhone 8 Plus 256GB Gold",
                price: 6388,
                count: 2,
                stock: 50
            },
            {
                id: 3,
                name: "小米电视4 55寸",
                price: 4499,
                count: 1,
                stock: 2
            },
            {
                id: 4,
                name: "小米电视4A 32寸",
                price: 999,
                count: 1,
                stock: 50
            }
        ],
        lang: {
            cantLessThanZero: '值不能小于 0!',
            outOfStock: '没有那么多库存了!'
        }
    },
    methods: {
        outOfStock: function (item) {
            if(item.count < 0) {
                item.count = 0;
                alert(this.lang.cantLessThanZero);
            }
            if(item.count > item.stock) {
                item.count = item.stock;
                alert(this.lang.outOfStock);
            }
        },
        deleteItem: function (item) {
            var _sku = this.sku;
            var index = _sku.indexOf(item);
            _sku.splice(index, 1);
        },
        addItem: function (item) {
            var _sku = this.sku;
            var index = _sku.indexOf(item);
            if(index > -1) {
                _sku[index].count < _sku[index].stock && _sku[index].count++;
            } else {
                _sku.push(item);
            }
        }
    },
    computed: {
        totalPrice: function () {
            var sum = 0;
            this.sku.forEach(function (o) {
                sum += o.price * o.count;
            });
            return sum;
        }
    }
});
</script>
</body>
</html>



觉得有用请点个赞吧!
1 694