cart.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <template>
  2. <view>
  3. <view v-if="!vuex_token" class="container">
  4. <view class="empty">
  5. <image :src="empty" style="width: 200px;height: 200px;"></image>
  6. <view class="title">请先登录</view>
  7. <view class="tip">别忘了买点什么犒劳一下自己哦</view>
  8. <view class="btn" @click="login">立即登录</view>
  9. </view>
  10. </view>
  11. <view v-else-if="vuex_token" class="container">
  12. <view v-if="cartList.length>0" class="cartList">
  13. <scroll-view scroll-y="true" style="margin-bottom: 100rpx;">
  14. <u-swipe-action v-for="(item, index) in cartList" :key="index"
  15. :index="index" :options="options"
  16. :show="item.show" @click="click"
  17. @open="open"
  18. >
  19. <view class="cartItem">
  20. <view @click="checkSelf(item)">
  21. <u-icon :style="{background:item.check?'#ff536f':'#eee'}" class="checkbox" color="#fff" name="checkbox-mark"
  22. size="20"></u-icon>
  23. </view>
  24. <view class="goosImg">
  25. <image :src="item.image" mode="widthFix" style="width: 200rpx;height: 200rpx;"></image>
  26. </view>
  27. <view class="goosMsg">
  28. <view class="title">
  29. {{ item.title }}
  30. </view>
  31. <view class="desc">
  32. {{ item.desc }}
  33. </view>
  34. <view class="goosBottom">
  35. <view class="left">{{ item.price }}</view>
  36. <view class="right">
  37. <u-number-box
  38. v-model="item.value" @change="changeValue"></u-number-box>
  39. </view>
  40. </view>
  41. </view>
  42. </view>
  43. </u-swipe-action>
  44. </scroll-view>
  45. <view class="bottomView">
  46. <view class="bottomLeft" @click="checkGoods">
  47. <u-icon :style="{background:checkAll?'#ff536f':'#eee'}" class="checkbox" color="#fff" name="checkbox-mark"
  48. size="25"></u-icon>
  49. <view class="clear">
  50. {{ checkGoodName }}
  51. </view>
  52. </view>
  53. <view class="bottomRight">
  54. <view class="left">
  55. ¥{{ totalPrice }}
  56. </view>
  57. <view class="right" @click="quote">
  58. 去结算({{ getcheckedGoods }})
  59. </view>
  60. </view>
  61. </view>
  62. </view>
  63. <view v-else class="empty">
  64. <image :src="empty" style="width: 200px;height: 200px;"></image>
  65. <view class="title">空空如也</view>
  66. <view class="tip">别忘了买点什么犒劳一下自己哦</view>
  67. <view class="btn" @click="searchList">随便逛逛</view>
  68. </view>
  69. </view>
  70. </view>
  71. </template>
  72. <script>
  73. export default {
  74. data() {
  75. return {
  76. cartList: [],
  77. checkAll: false,
  78. totalPrice: 0,
  79. checkedGoods: 0,
  80. checkGoodName: '全选',
  81. empty: '/static/empty/cart.png',
  82. options: [
  83. {
  84. text: '删除',
  85. style: {
  86. backgroundColor: '#ff536f'
  87. }
  88. }
  89. ],
  90. };
  91. },
  92. onShow() {
  93. if (this.vuex_token) {
  94. this.findCartList()
  95. }
  96. },
  97. computed: {
  98. getcheckedGoods: function () {
  99. let checkedGoods = 0
  100. this.cartList.filter(item => {
  101. if (item.check) {
  102. checkedGoods++
  103. }
  104. })
  105. return this.checkedGoods = checkedGoods
  106. }
  107. },
  108. methods: {
  109. click(index, index1) {
  110. // 计算价格
  111. if (this.cartList[index].check) {
  112. this.totalPrice = this.totalPrice - this.cartList[index].price
  113. }
  114. this.cartList.splice(index, 1);
  115. this.$mytip.toast('删除成功')
  116. this.$u.vuex('vuex_cartList', this.cartList);
  117. let badge = this.vuex_cartList.length
  118. // 设置tab badge
  119. if (badge > 0) {
  120. uni.setTabBarBadge({ //显示数字
  121. index: 2,
  122. text: '' + badge + ''
  123. })
  124. } else {
  125. // 移除tab badge
  126. uni.removeTabBarBadge({
  127. index: 2
  128. })
  129. }
  130. },
  131. // 如果打开一个的时候,不需要关闭其他,则无需实现本方法
  132. open(index) {
  133. // 先将正在被操作的swipeAction标记为打开状态,否则由于props的特性限制,
  134. // 原本为'false',再次设置为'false'会无效
  135. this.cartList[index].show = true;
  136. this.cartList.map((val, idx) => {
  137. if (index != idx) this.cartList[idx].show = false;
  138. })
  139. },
  140. login() {
  141. this.$u.route('/pages/login/login')
  142. },
  143. searchList() {
  144. this.$u.route('/pages/search/searchList')
  145. },
  146. checkSelf(item) {
  147. if (item.check) {
  148. // 计算价格
  149. this.totalPrice = this.totalPrice - item.price * item.value
  150. item.check = false;
  151. } else {
  152. // 计算价格
  153. this.totalPrice = this.totalPrice + item.price * item.value
  154. item.check = true;
  155. }
  156. this.cartList.filter(item => {
  157. this.checkAll = true
  158. if (!item.check) {
  159. this.checkAll = false
  160. }
  161. })
  162. },
  163. checkGoods() {
  164. if (this.checkAll) {
  165. this.checkAll = false;
  166. this.cartList.map((val, idx) => {
  167. this.cartList[idx].check = false;
  168. })
  169. // 计算价格
  170. this.totalPrice = 0
  171. this.checkGoodName = '全选'
  172. } else {
  173. this.checkAll = true;
  174. this.cartList.map((val, idx) => {
  175. // 计算价格
  176. this.totalPrice = this.totalPrice + this.cartList[idx].price * this.cartList[idx].value
  177. this.cartList[idx].check = true;
  178. })
  179. this.checkGoodName = '取消'
  180. }
  181. },
  182. changeValue(value) {
  183. this.totalPrice = 0
  184. this.cartList.map((val, idx) => {
  185. if (this.cartList[idx].check) {
  186. // 计算价格
  187. this.totalPrice = this.totalPrice + this.cartList[idx].price * this.cartList[idx].value
  188. }
  189. })
  190. },
  191. findCartList() {
  192. this.cartList = this.vuex_cartList.reverse()
  193. let badge = this.vuex_cartList.length
  194. // 设置tab badge
  195. if (badge > 0) {
  196. uni.setTabBarBadge({ //显示数字
  197. index: 2,
  198. text: '' + badge + ''
  199. })
  200. }
  201. },
  202. quote() {
  203. if (this.checkedGoods == 0) {
  204. return this.$mytip.toast('请选中需要结算的商品')
  205. }
  206. this.$u.route('/pages/order/preOrder')
  207. },
  208. }
  209. };
  210. </script>
  211. <style>
  212. page {
  213. background-color: #fff;
  214. }
  215. </style>
  216. <style lang="scss" scoped>
  217. .container {
  218. width: 100%;
  219. background-color: #ffffff;
  220. text-align: center;
  221. overflow: hidden;
  222. .cartList {
  223. text-align: left;
  224. .cartItem {
  225. margin: 0 20 rpx;
  226. display: flex;
  227. align-items: center;
  228. line-height: 2;
  229. .checkbox {
  230. background: #ff536f;
  231. border-radius: 100%;
  232. margin-right: 20 rpx;
  233. padding: 8 rpx;
  234. }
  235. .goosMsg {
  236. margin-left: 20 rpx;
  237. .title {
  238. width: 430 rpx;
  239. margin-top: -20rpx;
  240. font-size: 28 rpx;
  241. color: $u-main-color;
  242. font-weight: 800;
  243. text-overflow: ellipsis;
  244. overflow: hidden;
  245. white-space: normal;
  246. overflow: hidden;
  247. text-overflow: ellipsis;
  248. display: -webkit-box;
  249. -webkit-box-orient: vertical;
  250. -webkit-line-clamp: 1;
  251. height: 35px;
  252. max-height: 35px;
  253. }
  254. .desc {
  255. font-weight: normal;
  256. font-size: 22 rpx;
  257. color: $u-tips-color;
  258. }
  259. }
  260. .goosBottom {
  261. margin-top: 20 rpx;
  262. display: flex;
  263. align-items: center;
  264. justify-content: space-between;
  265. .num {
  266. font-size: 26 rpx;
  267. color: $u-main-color;
  268. font-weight: 800;
  269. }
  270. .right {
  271. font-size: 26 rpx;
  272. color: $u-main-color;
  273. }
  274. }
  275. }
  276. .bottomView {
  277. box-shadow: 0 -1px 1px 0 rgba(0, 0, 0, 0.05);
  278. position: fixed;
  279. left: 0;
  280. right: 0;
  281. /* #ifdef H5 */
  282. bottom: 95 rpx;
  283. /* #endif */
  284. /* #ifdef MP */
  285. bottom: 0;
  286. /* #endif */
  287. background-color: #ffffff;
  288. z-index: 999;
  289. height: 100 rpx;
  290. line-height: 100 rpx;
  291. display: flex;
  292. justify-content: space-between;
  293. align-items: center;
  294. padding: 20 rpx;
  295. .bottomLeft {
  296. display: flex;
  297. align-items: center;
  298. position: relative;
  299. height: 100 rpx;
  300. line-height: 100 rpx;
  301. .checkbox {
  302. border-radius: 100%;
  303. margin-right: 20 rpx;
  304. margin-top: 10 rpx;
  305. padding: 8 rpx;
  306. z-index: 1;
  307. }
  308. .clear {
  309. width: 120 rpx;
  310. padding: 5 rpx;
  311. height: 100 rpx;
  312. line-height: 100 rpx;
  313. text-align: center;
  314. border-radius: 10%;
  315. position: absolute;
  316. left: 30 rpx;
  317. z-index: 0;
  318. color: #999;
  319. font-size: 16px;
  320. }
  321. }
  322. .bottomRight {
  323. display: flex;
  324. align-items: center;
  325. height: 60 rpx;
  326. line-height: 60 rpx;
  327. .left {
  328. color: $base-color;
  329. font-size: 18px;
  330. font-weight: 800;
  331. margin-right: 20 rpx;
  332. }
  333. .right {
  334. color: #fff;
  335. background: $base-color;
  336. padding: 2 rpx 20 rpx;
  337. border-radius: 30 rpx;
  338. margin-left: 20 rpx;
  339. }
  340. ;
  341. }
  342. }
  343. }
  344. .empty {
  345. margin-top: 220 rpx;
  346. width: 100%;
  347. text-align: center;
  348. .title {
  349. color: $u-main-color;
  350. margin: 20 rpx 0 10 rpx 0;
  351. font-weight: 400;
  352. font-size: 18px;
  353. }
  354. .tip {
  355. color: $u-tips-color;
  356. font-size: 14px;
  357. }
  358. .btn {
  359. color: #fff;
  360. background-image: linear-gradient(to left, #ff536f, rgba(#ff536f, 0.6));
  361. width: 200 rpx;
  362. padding: 15 rpx 28 rpx;
  363. border-radius: 130 rpx;
  364. margin: 80 rpx 0 0 275 rpx;
  365. }
  366. }
  367. }
  368. </style>