案例要求:
代码:
<!DOCTYPE html> <html lang="en"> <head> ?<meta charset="UTF-8"> ?<meta http-equiv="X-UA-Compatible" content="IE=edge"> ?<meta name="viewport" content="width=device-width, initial-scale=1.0"> ?<title>Document</title> ?<link rel="stylesheet" href="./style.css"> </head> <body> ? ?<div id="app"></div> ? ?<template id="my-app"> ? ?<template v-if="books.length > 0"> ? ? ?<table> ? ? ? ?<thead> ? ? ? ? ?<th>序号</th> ? ? ? ? ?<th>书籍名称</th> ? ? ? ? ?<th>出版日期</th> ? ? ? ? ?<th>价格</th> ? ? ? ? ?<th>购买数量</th> ? ? ? ? ?<th>操作</th> ? ? ? ?</thead> ? ? ? ?<tbody> ? ? ? ? ?<tr v-for="(book, index) in books"> ? ? ? ? ? ?<td>{{index + 1}}</td> ? ? ? ? ? ?<td>{{book.name}}</td> ? ? ? ? ? ?<td>{{book.date}}</td> ? ? ? ? ? ?<td>{{formatPrice(book.price)}}</td> ? ? ? ? ? ?<td> ? ? ? ? ? ? ?<button :disabled="book.count <= 1" @click="decrement(index)">-</button> ? ? ? ? ? ? ?<span class="counter">{{book.count}}</span> ? ? ? ? ? ? ?<button @click="increment(index)">+</button> ? ? ? ? ? ?</td> ? ? ? ? ? ?<td> ? ? ? ? ? ? ?<button @click="removeBook(index)">移除</button> ? ? ? ? ? ?</td> ? ? ? ? ?</tr> ? ? ? ?</tbody> ? ? ?</table> ? ? ?<h2>总价格: {{formatPrice(totalPrice)}}</h2> ? ?</template> ? ?<template v-else> ? ? ?<h2>购物车为空~</h2> ? ?</template> ?</template> ? ?<script src="../js/vue.js"></script> ?<script src="./index.js"></script> ? </body> </html>Vue.createApp({ ?template: "#my-app", ?data() { ? ?return { ? ? ?books: [ ? ? ? { ? ? ? ? ?id: 1, ? ? ? ? ?name: '《算法导论》', ? ? ? ? ?date: '2006-9', ? ? ? ? ?price: 85.00, ? ? ? ? ?count: 1 ? ? ? }, ? ? ? { ? ? ? ? ?id: 2, ? ? ? ? ?name: '《UNIX编程艺术》', ? ? ? ? ?date: '2006-2', ? ? ? ? ?price: 59.00, ? ? ? ? ?count: 1 ? ? ? }, ? ? ? { ? ? ? ? ?id: 3, ? ? ? ? ?name: '《编程珠玑》', ? ? ? ? ?date: '2008-10', ? ? ? ? ?price: 39.00, ? ? ? ? ?count: 1 ? ? ? }, ? ? ? { ? ? ? ? ?id: 4, ? ? ? ? ?name: '《代码大全》', ? ? ? ? ?date: '2006-3', ? ? ? ? ?price: 128.00, ? ? ? ? ?count: 1 ? ? ? }, ? ? ] ? } }, ?computed: { ? ?// vue2: filter/map/reduce ? ?totalPrice() { ? ? ?let finalPrice = 0; ? ? ?for (let book of this.books) { ? ? ? ?finalPrice += book.count * book.price; ? ? } ? ? ?return finalPrice; ? }, ? ?// Vue3不支持过滤器了, 推荐两种做法: 使用计算属性/使用全局的方法 ? ?filterBooks() { ? ? ?return this.books.map(item => { ? ? ? ?const newItem = Object.assign({}, item); ? ? ? ?newItem.price = "¥" + item.price; ? ? ? ?return newItem; ? ? }) ? } }, ?methods: { ? ?increment(index) { ? ? ?// 通过索引值获取到对象 ? ? ?this.books[index].count++ ? }, ? ?decrement(index) { ? ? ?this.books[index].count-- ? }, ? ?removeBook(index) { ? ? ?this.books.splice(index, 1); ? }, ? ?formatPrice(price) { ? ? ?return "¥" + price; ? } } }).mount("#app");table { ?border: 1px solid #e9e9e9; ?border-collapse: collapse; ?border-spacing: 0; } ? th, td { ?padding: 8px 16px; ?border: 1px solid #e9e9e9; ?text-align: left; } ? th { ?background-color: #f7f7f7; ?color: #5c6b77; ?font-weight: 600; } ? .counter { ?margin: 0 5px; }
代码解析:
创建button按钮,当执行减少选择图书的操作时,在index.js文件中调用decrement(index)函数,当book.count <= 1(即所选书本个数小于等于1时)执行布尔判断,为ture则button按钮不可被点击,为false则可以点击;当执行增加选择图书的操作时,在index.js文件中调用increment(index)函数
<td> ? ? <button :disabled="book.count <= 1" @click="decrement(index)">-</button> ? ? <span class="counter">{{book.count}}</span> ? ? <button @click="increment(index)">+</button> </td>
this.books.splice(index, 1);这句代码的含义是从index项开始索引,1表示从当前索引项开始(包含该索引项)向下索引个数
<td> ? ? <button @click="removeBook(index)">移除</button> </td>removeBook(index) { ? this.books.splice(index, 1); },
这段代码表示如果有选中图书,则进行app操作;若全部移除图书之后,则在页面上显示购物车为空~
<template v-if="books.length > 0"> ? ? </template> <template v-else> ? <h2>购物车为空~</h2> </template>
这段代码计算图书总金额,注意computed:的使用
computed: { ? ?totalPrice() { ? ? ?let finalPrice = 0; ? ? ?for (let book of this.books) { ? ? ? ?finalPrice += book.count * book.price; ? ? } ? ? ?return finalPrice; ? },
这段CSS代码表示含义为给button按钮左右间距5px
.counter { ?margin: 0 5px; }