shop_list.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <view class="_list" @click="listClick">
  3. <view class="_list_top">
  4. <image
  5. :src="item.pic_url"
  6. lazy-load
  7. :draggable="false"
  8. mode="scaleToFill"
  9. class="img"
  10. ></image>
  11. </view>
  12. <view class="_list_bottom">
  13. <view class="_title">{{ item.title }}</view>
  14. <view class="_price">
  15. <rich-text
  16. class="texts"
  17. :nodes="MoneyAbouthtml(item.price, true)"
  18. ></rich-text>
  19. </view>
  20. </view>
  21. <view class="collect" @click.stop="startClick">
  22. <i
  23. class="icon-font"
  24. :class="item.isCollect ? 'icon-collected' : 'icon-not-collected'"
  25. ></i>
  26. </view>
  27. </view>
  28. </template>
  29. <script setup>
  30. import { Moneyhtml, MoneyAbouthtml } from "@/utils";
  31. import { useSystemStore } from "@/store";
  32. import { computed } from "vue";
  33. const useSystem = useSystemStore();
  34. const props = defineProps({
  35. item: {
  36. type: Object,
  37. default: () => ({}),
  38. },
  39. channel: {
  40. type: [String, Number],
  41. default: 0,
  42. },
  43. search: {
  44. type: String,
  45. default: "",
  46. },
  47. isFree: {
  48. type: [String, Number],
  49. default: 0,
  50. },
  51. });
  52. const emit = defineEmits(["listClick", "collect"]);
  53. const symbol = computed(() => useSystem.getSymbol);
  54. const listClick = () => {
  55. uni.navigateTo({
  56. url: `/pages/shop/productDetail?channel=${props.channel}&goods_id=${props.item.num_iid}&search=${props.search}&isFree=${props.isFree}`,
  57. });
  58. };
  59. const startClick = () => {
  60. emit("collect", props.item);
  61. };
  62. </script>
  63. <style lang="less" scoped>
  64. @import url("@/style.less");
  65. ._list {
  66. overflow: hidden;
  67. border-radius: 20rpx;
  68. background-color: var(--inputBg);
  69. width: 100%;
  70. .flex();
  71. flex-direction: column;
  72. position: relative;
  73. .collect {
  74. top: 24rpx;
  75. right: 24rpx;
  76. position: absolute;
  77. width: 64rpx;
  78. height: 64rpx;
  79. background-color: #dfe3eb;
  80. border-radius: 4px;
  81. box-shadow: 0 0.8px 8px #0000001a;
  82. opacity: 0.8;
  83. .flex_center();
  84. .icon-font {
  85. .size(20px);
  86. color: var(--primary);
  87. }
  88. }
  89. &_top {
  90. width: 100%;
  91. .img {
  92. width: 100%;
  93. height: 100%;
  94. object-fit: cover;
  95. aspect-ratio: 1 / 1;
  96. // border-radius: 8rpx;
  97. display: block;
  98. }
  99. }
  100. &_bottom {
  101. padding: 16rpx;
  102. ._title {
  103. .size(24rpx);
  104. line-height: 32rpx;
  105. .ellipsis(1);
  106. }
  107. ._price {
  108. .ver(flex-end);
  109. color: var(--red);
  110. .size(32rpx);
  111. font-weight: 700;
  112. margin-top: 8rpx;
  113. font-family: "HarmonyOS_Sans";
  114. .icon {
  115. margin-right: 8rpx;
  116. }
  117. .icon2 {
  118. margin: 0 8rpx;
  119. }
  120. .texts {
  121. /deep/ div {
  122. .ver(baseline);
  123. .price {
  124. }
  125. .decimal {
  126. .size(24rpx);
  127. }
  128. }
  129. }
  130. }
  131. }
  132. }
  133. </style>