Cart.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <template lang="pug">
  2. .cart(:style='{ width: defaultOptions.layout.width, height: defaultOptions.layout.height }')
  3. .cart-total
  4. h2.currency-cart-total {{ total | currency(...defaultOptions.currency) }}
  5. .cart-items-wrapper
  6. transition-group(name='list' tag='ul' class='cart-items')
  7. cart-item(v-for='(item, index) in items' :key='index' :index='index' :item='item' @onClickQuantity='onClickQuantity' @onChange='onItemChanged' @onClickIncrement='onIncrementQty' @onClickDecrement='onDecrementQty' @onClickMoney='onChangePrice' @onClickUndo='onUndoPrice' @onClickDelete='onDeleteItem' :options='defaultOptions.currency')
  8. </template>
  9. <script>
  10. import CartItem from './CartItem'
  11. export default {
  12. components: {
  13. CartItem
  14. },
  15. props: {
  16. items: {
  17. type: Array,
  18. default: [],
  19. required: true
  20. },
  21. options: {
  22. type: Object || String,
  23. default: null
  24. }
  25. },
  26. methods: {
  27. computeOptions(value) {
  28. if (!value) {
  29. return
  30. }
  31. for(let key in value) {
  32. if(!this.defaultOptions.currency[key]) {
  33. continue
  34. }
  35. this.defaultOptions.currency[key] = value[key]
  36. }
  37. },
  38. computeTotal() {
  39. let sum = 0
  40. for (let item of this.items) {
  41. sum = sum + ((item.price || 0) * (item.quantity || 0))
  42. }
  43. this.total = sum
  44. this.$emit('onTotalComputed', this.total)
  45. },
  46. onItemChanged(item) {
  47. this.computeTotal();
  48. },
  49. onIncrementQty(item) {
  50. this.$emit('onIncrementQty', item)
  51. },
  52. onDecrementQty(item) {
  53. this.$emit('onDecrementQty', item)
  54. },
  55. onChangePrice(item) {
  56. this.$emit('onChangePrice', item)
  57. },
  58. onUndoPrice(item) {
  59. this.$emit('onUndoPrice', item)
  60. },
  61. onDeleteItem(item) {
  62. this.$emit('onDeleteItem', item)
  63. }
  64. },
  65. watch: {
  66. items() {
  67. this.computeTotal()
  68. },
  69. options(value) {
  70. this.computeOptions(value)
  71. }
  72. },
  73. data() {
  74. return {
  75. total: 0,
  76. defaultOptions: {
  77. currency: {
  78. symbol: '$',
  79. position: 'before',
  80. thousandsSeparator: '.',
  81. decimalPlaces: 2,
  82. decimalSeparator: ','
  83. },
  84. layout: {
  85. width: '300px',
  86. height: '100%'
  87. }
  88. }
  89. }
  90. }
  91. }
  92. </script>
  93. <style lang="sass">
  94. @import '../../assets/variables'
  95. .cart
  96. border-left: 1px solid $app-border-color
  97. padding-left: 10px
  98. display: inline-block
  99. vertical-align: top
  100. .cart-total
  101. width: 100%
  102. height: 50px
  103. .currency-cart-total
  104. width: 100%
  105. height: 50px
  106. margin: 0
  107. font-size: 30pt
  108. .cart-items-wrapper
  109. width: 100%
  110. height: calc(100% - 100px)
  111. overflow-y: auto
  112. overflow-x: hidden
  113. &::-webkit-scrollbar
  114. width: 2px
  115. background: #f5f5f5
  116. &::-webkit-scrollbar-thumb
  117. background: #7c7bad
  118. &::-webkit-scrollbar-track
  119. -webkit-box-shadow: inset 0 0 6px #d3d3d3
  120. background: #f5f5f5
  121. .cart-items
  122. width: 100%
  123. padding: 0
  124. margin: 0
  125. .list-enter-active, .list-leave-active
  126. transition: all 0.3s
  127. .list-enter, .list-leave-to
  128. opacity: 0
  129. transform: translateX(300px)
  130. </style>