博客列表 >原生购物车Vue改写

原生购物车Vue改写

Blackeye
Blackeye原创
2022年04月17日 14:39:05481浏览

LNjN3q.gif

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>购物车_vue</title>
  8. <script src="https://unpkg.com/vue@next"></script>
  9. <style>
  10. *{
  11. margin: 0;
  12. padding: 0;
  13. box-sizing: border-box;
  14. }
  15. .box {
  16. width: 35em;
  17. height: 2em;
  18. margin: auto;
  19. }
  20. .list > li {
  21. height: 1.6em;
  22. background-color: #efefef;
  23. display: grid;
  24. grid-template-columns: repeat(5, 6em);
  25. gap: 1em;
  26. place-items: center left;
  27. border-bottom: 1px solid #ccc;
  28. }
  29. .list > li:first-of-type {
  30. background-color: rgb(33, 91, 138);
  31. color: white;
  32. }
  33. .list > li:hover:not(:first-of-type) {
  34. cursor: pointer;
  35. background-color: rgb(85, 125, 212);
  36. }
  37. .list > li input[type="number"] {
  38. width: 3em;
  39. border: none;
  40. outline: none;
  41. text-align: center;
  42. font-size: 1em;
  43. background-color: transparent;
  44. }
  45. .list > li:nth-last-of-type(2) span.total-num,
  46. .list > li:nth-last-of-type(2) span.total-amount {
  47. grid-column: span 2;
  48. place-self: center left;
  49. color: rgb(85, 125, 212);
  50. }
  51. .list > li:last-of-type span{
  52. grid-column: span 2;
  53. place-self: center right;
  54. color: red;
  55. }
  56. </style>
  57. </head>
  58. <body>
  59. <!-- vue挂载点 -->
  60. <div class="app">
  61. <div class="box" @change="updata($event)">
  62. <div class="select-all" @click="selectAll=!selectAll">
  63. <input type="checkbox" class="check-all" :checked="selectAll"/>
  64. <label for="check-all">全选</label>
  65. </div>
  66. <ul class="list" ref="list">
  67. <!-- 表单头 -->
  68. <li>
  69. <span v-for="(item, index) of shopCartList" :key="index"
  70. >{{item}}</span
  71. >
  72. </li>
  73. <!-- 商品list -->
  74. <Item-list name="手机" price="100"></Item-list>
  75. <Item-list name="电脑" price="200"></Item-list>
  76. <Item-list name="相机" price="300"></Item-list>
  77. <Item-list name="冰箱" price="400"></Item-list>
  78. <li>
  79. <span>总计</span>
  80. <span class="total-num">数量: {{numbers}}</span>
  81. <span class="total-amount">总金额: {{totalPay}}</span>
  82. </li>
  83. <li>
  84. <span>折扣金额: {{disCount}}</span>
  85. <span>应付金额: {{disPay}}</span>
  86. </li>
  87. </ul>
  88. </div>
  89. </div>
  90. <!-- 商品list模板 -->
  91. <template id="itemLists">
  92. <li>
  93. <input type="checkbox"/>
  94. <span class="content">{{name}}</span>
  95. <input type="number" v-model="num" min="1"/>
  96. <span class="price">{{price}}</span>
  97. <span class="amount">{{payAmount}}</span>
  98. </li>
  99. </template>
  100. </body>
  101. <script>
  102. // vue实例
  103. const app = Vue.createApp({
  104. data() {
  105. return {
  106. shopCartList: ["选择", "品名", "数量", "单价", "金额"],
  107. numbers:0,
  108. totalPay:0,
  109. disCount:0,
  110. disPay:0,
  111. selectAll:true
  112. };
  113. },
  114. methods:{
  115. updata(el){
  116. if(this.selectAll && ( el===0 || (el.target.className==="check-all") )){
  117. [...document.querySelectorAll(".list>li input[type='checkbox']")].map(item=>item.checked=true);
  118. }else if(el===0 ||el.target.className==="check-all"){
  119. [...document.querySelectorAll(".list>li input[type='checkbox']")].map(item=>item.checked=false);
  120. }
  121. const item_ck = [...document.querySelectorAll(".list>li input[type='checkbox']")];
  122. if(item_ck.every(item=>item.checked)){
  123. this.selectAll=true;
  124. }else{
  125. this.selectAll=false;
  126. }
  127. const item_price = [...document.querySelectorAll(".price")];
  128. const item_num = [...document.querySelectorAll(".list>li input[type='number']")];
  129. // item_ck.forEach(item=>console.log(item.checked));
  130. let temp_num_list = item_num.map((item,index)=>{
  131. if(item_ck[index].checked){
  132. return parseInt(item.value);
  133. }else{
  134. return 0;
  135. }
  136. });
  137. this.numbers = temp_num_list.reduce((res,index)=>res+index);
  138. this.totalPay = temp_num_list.map((item,index)=>item*item_price[index].textContent).reduce((acc,index)=>acc+index);
  139. }
  140. },
  141. watch:{
  142. totalPay(current,origin){
  143. switch(true){
  144. case current>=600:
  145. this.disCount=100;
  146. break;
  147. default:
  148. this.disCount = 0;
  149. }
  150. this.disPay = current-this.disCount;
  151. }
  152. },
  153. mounted(){
  154. this.$nextTick(function(){
  155. this.updata(0);
  156. })
  157. },
  158. });
  159. // 注册组件
  160. app.component("ItemList", {
  161. template: "#itemLists",
  162. props: ["name", "price"],
  163. data(){
  164. return {
  165. num:1,
  166. };
  167. },
  168. computed:{
  169. payAmount(){
  170. return this.num*this.price;
  171. }
  172. }
  173. });
  174. // 挂载实例
  175. app.mount(".app");
  176. </script>
  177. </html>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议