cart.gif

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name=referrer content=never>
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8. <title>Document</title>
  9. <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.css" rel="stylesheet">
  10. <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
  11. <script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.js"></script>
  12. <style>
  13. img {
  14. width: 40px;
  15. height: 65px;
  16. }
  17. .count {
  18. width: 40px;
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <div id="app" class="container">
  24. <h2 class="text-success text-center">购物车</h2>
  25. <table class="table table-bordered table-hover">
  26. <thead>
  27. <tr>
  28. <th>全选 <input type="checkbox" v-model="checkAll" @change="change"></th>
  29. <th>商品</th>
  30. <th>单价</th>
  31. <th>数量</th>
  32. <th>小计</th>
  33. <th>操作</th>
  34. </tr>
  35. </thead>
  36. <tbody>
  37. <tr v-for="(item,index) of products">
  38. <td><input type="checkbox"
  39. @change="handleItem()"
  40. v-model="item.isSelected"></td>
  41. <td><img :src="item.productCover" :alt="item.productName"> {{item.productName}}</td>
  42. <td>{{item.productPrice}}</td>
  43. <td><input class="count" v-model.number="item.productCount" type="number" min="1"></td>
  44. <td>{{item.productPrice*item.productCount | toFixed}}</td>
  45. <td><button class="btn btn-danger" @click="remove(index)">删除</button></td>
  46. </tr>
  47. </tbody>
  48. </table>
  49. <p>总价格:{{sum() | toFixed}}</p>
  50. </div>
  51. <script>
  52. var vm = new Vue({
  53. el: "#app",
  54. filters: {
  55. toFixed(value) {
  56. return "$" + value.toFixed(2)
  57. }
  58. },
  59. data: {
  60. products: [],
  61. checkAll: false
  62. },
  63. mounted() {
  64. axios.get('./data/carts.json').then(res => {
  65. this.products = res.data
  66. })
  67. this.handleItem()
  68. },
  69. methods: {
  70. remove(index) {
  71. this.products.splice(index, 1)
  72. },
  73. change() {
  74. console.log(this.checkAll)
  75. this.products.forEach(item => item.isSelected = this.checkAll)
  76. },
  77. handleItem(){
  78. /* 根据列表项点击的结果控制全选的结果 */
  79. this.checkAll = this.products.every(item=>item.isSelected)
  80. },
  81. sum(){
  82. // alert(1)
  83. var sum = 0;
  84. this.products.forEach(item=>{
  85. sum = item["productCount"]*item["productPrice"]+sum;
  86. console.log(sum)
  87. })
  88. return sum;
  89. }
  90. }
  91. })
  92. </script>
  93. </body>
  94. </html>

一、sum()求和带来的问题

  1. //只要products改变的时候,sum函数就会触发。这样不利于性能优化

二、使用computed属性改造代码

2-1 计算属性控制选中和没有选中的状态

  1. var vm = new Vue({
  2. el: "#app",
  3. ...
  4. computed:{
  5. checkAll:{
  6. /* products值变化时会重新计算 */
  7. get(){
  8. return this.products.every(item=>item.isSelected)
  9. },
  10. set(val){
  11. //给checkbox赋值的时候触发
  12. this.products.forEach(item=>item.isSelected = val)
  13. }
  14. }
  15. },
  16. data: {
  17. products: []
  18. },
  19. mounted() {
  20. axios.get('./data/carts.json').then(res => {
  21. this.products = res.data
  22. })
  23. }
  24. })

2-2 计算总价格

  1. computed:{
  2. ....
  3. sum(){
  4. /* sum的值会被缓存,如果依赖的数据没有变化不会重新执行 */
  5. var total = 0;
  6. this.products.forEach(item=>{
  7. total = item['productPrice']*item['productCount']+total;
  8. })
  9. return total;
  10. }
  11. }