1.index.vue

1.1安装依赖

  1. yarn add axios vant amfe-flexible router

1.2引入依赖 main.js

  1. import Vue from 'vue'
  2. import router from './router'
  3. import 'amfe-flexible/index.js'
  4. import Vant from 'vant'
  5. import 'vant/lib/index.css'
  6. import axios from 'axios'
  7. Vue.config.productionTip = false
  8. Vue.filter("formats",function(val,params){
  9. return "$"+val.toFixed(params);
  10. }
  11. )
  12. Vue.filter("format",function(val){
  13. if(val.length>7){
  14. val=val.slice(0,7)+'...'
  15. }
  16. return val
  17. })
  18. Vue.use(Vant)
  19. Vue.prototype.axios=axios;

1.3新建组件components/Shop.vue

  1. <template>
  2. <div class="container">
  3. <div class="box">
  4. <p>购物车</p>
  5. <p>您确定要删除这件商品吗?</p>
  6. <button @click="handleCancel">取消</button>
  7. <button @click="handleDelete">确定删除</button>
  8. </div>
  9. </div>
  10. </template>
  11. <script>
  12. export default {
  13. name:"Shop",
  14. methods:{
  15. handleCancel(){
  16. this.$emit("can") //取消
  17. },
  18. handleDelete(){
  19. this.$emit("del") //删除
  20. }
  21. }
  22. }
  23. </script>

1.4Cart/index.vue中引入组件

  1. //1.引入组件
  2. import Shop from '@/components/Shop.vue'
  3. //2.注册组件
  4. components:{
  5. Shop
  6. }
  7. //3.使用组件
  8. //isShow:是否显示组件 @can:取消 @del:删除
  9. <Shop v-show="isShow" @can="handleCancel" @del="handleDelete"></Shop>

1.5核心业务

  1. //1.给按钮进行一个切换的动作,点击删除按钮会出现一个模态框
  2. <button class="del" @click="toggle" >删除</button>
  3. export default{
  4. data(){
  5. return{
  6. isShow:false
  7. }
  8. },
  9. methods:{
  10. toggle(){ //模态框显示
  11. this.isShow=true;
  12. },
  13. handleCancel(){
  14. this.isShow=false //取消时模态框不显示
  15. },
  16. handleDelete(index){
  17. this.products.splice(index,1) //点击删除时删除一条数据,同时模态框不显示
  18. this.isShow=false
  19. }
  20. }
  21. }
  1. <template>
  2. <div class="cart">
  3. <div class="item list" v-for="(item,index) of products" :key="item.id" :index="index">
  4. <div class="list icon f1">
  5. <van-checkbox v-model="item.isSelected" icon-size="23px"></van-checkbox>
  6. </div>
  7. <div class="pic">
  8. <img :src="item.productCover" alt />
  9. </div>
  10. <div class="f3">
  11. <div>
  12. <p class="red">{{item.productName | format(9)}}</p>
  13. <p>{{item.productInfo | format(9)}}</p>
  14. <p>
  15. {{item.productPrice}}元
  16. <span class="price">小计:{{item.productCount*item.productPrice | formats(2)}}元</span>
  17. </p>
  18. <van-stepper v-model="item.productCount" min="1" button-size="23px" />
  19. </div>
  20. </div>
  21. <div class="f2 icon list">
  22. <button class="del" @click="toggle" >删除</button>
  23. </div>
  24. </div>
  25. <div class="footer list">
  26. <div class="list icon f2">
  27. <van-checkbox v-model="checked" icon-size="23px">全选</van-checkbox>
  28. </div>
  29. <div class="list icon f3">总计:{{sum | formats(2)}}元</div>
  30. <div class="f2">
  31. <button class="confirm">确定</button>
  32. </div>
  33. </div>
  34. <Shop v-show="isShow" @can="handleCancel" @del="handleDelete"></Shop>
  35. </div>
  36. </template>
  37. <script>
  38. import Shop from '@/components/Shop.vue'
  39. export default {
  40. name: "Cart",
  41. data() {
  42. return {
  43. products: [],
  44. isShow:false
  45. };
  46. },
  47. components:{
  48. Shop
  49. },
  50. mounted() {
  51. var url="http://yapi.demo.qunar.com/mock/34774/"
  52. this.axios.get(url).then(res => {
  53. this.products = res.data;
  54. });
  55. },
  56. methods: {
  57. toggle(){
  58. this.isShow=true;
  59. },
  60. handleCancel(){
  61. this.isShow=false
  62. },
  63. handleDelete(index){
  64. this.products.splice(index,1)
  65. this.isShow=false
  66. }
  67. },
  68. computed: {
  69. sum() {
  70. var val;
  71. val = 0;
  72. this.datas.forEach(item => {
  73. if (item.isSelected) {
  74. val = val + item.productCount * item.productPrice;
  75. }
  76. });
  77. return val;
  78. },
  79. checked: {
  80. get() {
  81. return this.products.every(item => item.isSelected);
  82. },
  83. set(val) {
  84. this.products.forEach(item => (item.isSelected = val));
  85. }
  86. }
  87. }
  88. };
  89. </script>
  90. <style scoped>
  91. .footer {
  92. position: fixed;
  93. bottom: 30px;
  94. width: 100%;
  95. background: #ddd;
  96. }
  97. .confirm {
  98. position: relative;
  99. right: -30px;
  100. width: 150px;
  101. height: 80px;
  102. background: red;
  103. outline: none;
  104. border-radius: 5px;
  105. color: #fff;
  106. }
  107. .red {
  108. color: rgb(182, 51, 51);
  109. font-size: 32px;
  110. }
  111. .price{
  112. margin-left: 10px;
  113. }
  114. p {
  115. margin-bottom: 20px;
  116. }
  117. .item {
  118. padding: 10px 0;
  119. }
  120. .pic img {
  121. width: 160px;
  122. height: 240px;
  123. border-radius: 10px;
  124. margin-top: 20px;
  125. }
  126. .list {
  127. display: flex;
  128. }
  129. .icon {
  130. justify-content: center;
  131. align-items: center;
  132. }
  133. .f1 {
  134. flex: 1;
  135. }
  136. .f2 {
  137. flex: 2;
  138. }
  139. .f3 {
  140. flex: 5;
  141. }
  142. .del {
  143. color: #fff;
  144. width: 130px;
  145. height: 80px;
  146. background: red;
  147. outline: none;
  148. border-radius: 5px;
  149. }
  150. .cart{
  151. font-size: 28px;
  152. }
  153. </style>