imPony 发布于:2017-11-24 10:42:40
前言
经过近四年的发展,Vue.js 这个尤雨溪一个人开发的框架几乎可以和 Facebook 一个团队开发的 React 抗衡。
Vue.js 对大家来说是个新东西,也是非常重要的东西,它和 jQuery 编程是完全不同的思路,是目前 Web 应用的主流开发框架。
互动:
解释什么是状态
询问大家购物车应该具备哪些功能?对于 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>
互动:思考数据应该怎么组织,哪些数据是变量,哪些是需要实时更新的变量?
第二步
要点:
v-bind、v-model
{{ 变量、表达式 }}
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 }, ] } });
互动:应该如何来组织行为?
第三步
要点:
v-bind、v-on
v-on 时执行的方法
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>
登录后可以留言提问!
微信扫码登录