list.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. <template>
  2. <view class="content">
  3. <view class="navbar" :style="{position:headerPosition,top:headerTop}">
  4. <view class="nav-item" :class="{current: filterIndex === 0}" @click="tabClick(0)">
  5. 销量优先
  6. </view>
  7. <view class="nav-item" :class="{current: filterIndex === 1}" @click="tabClick(1)">
  8. <text>价格</text>
  9. <view class="p-box">
  10. <text :class="{active: priceOrder === 1 && filterIndex === 1}" class="yticon icon-shang"></text>
  11. <text :class="{active: priceOrder === 2 && filterIndex === 1}" class="yticon icon-shang xia"></text>
  12. </view>
  13. </view>
  14. </view>
  15. <view class="goods-list">
  16. <view v-for="(item, index) in goodsList" :key="index" class="goods-item" @click="navToDetailPage(item)">
  17. <view class="image-wrapper">
  18. <image :src="JSON.parse(item.image)[0].url " mode="aspectFill"></image>
  19. </view>
  20. <text class="title clamp">{{item.storeName}}</text>
  21. <!-- <view class="price-box"> -->
  22. <!-- <text class="price">{{isVip? (item.vipPrice / 100.0 + ' [VIP]') : (item.price / 100.0)}}<text class="text-df text-gray">/{{item.unit}}</text></text> -->
  23. <view class="price-box">
  24. <view class="">
  25. <text style="font-size: 36rpx;" class="price">{{item.kxStockVo.price}}</text>
  26. <text class="text-gray text-df" style="font-size: 24rpx;">/{{item.unitName}}</text>
  27. </view>
  28. <!-- <text v-if="item.spuotPrice > (isVip ? item.spuVipPrice : item.spuPrice)" class="m-price">¥{{item.spuotPrice / 100}}</text> -->
  29. <text>{{item.kxStockVo.sales?item.kxStockVo.sales:0}}人已购买</text>
  30. </view>
  31. <!-- <text>{{item.sales?item.sales:0}}人已购买</text> -->
  32. <!-- </view> -->
  33. </view>
  34. </view>
  35. <uni-load-more :status="loadingType"></uni-load-more>
  36. </view>
  37. </template>
  38. <script>
  39. // import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
  40. export default {
  41. components: {
  42. // uniLoadMore
  43. },
  44. data() {
  45. return {
  46. cateMaskState: 0, //分类面板展开状态
  47. headerPosition: "fixed",
  48. headerTop: "0px",
  49. loadingType: 'more', //加载更多状态
  50. filterIndex: 0,
  51. priceOrder: 0, //1 价格从低到高 2价格从高到低
  52. goodsList: [],
  53. cateId: 0,
  54. keywords: '',
  55. pageNo: 1,
  56. isVip: false
  57. };
  58. },
  59. onShow() {
  60. this.isVip = this.$api.isVip()
  61. },
  62. onLoad(options) {
  63. // #ifdef H5
  64. if (this.$store.state.headerTop) {
  65. this.headerTop = this.$store.state.headerTop
  66. } else {
  67. this.headerTop = document.getElementsByTagName('uni-page-head')[0].offsetHeight + 'px';
  68. this.$store.state.headerTop = this.headerTop
  69. }
  70. // #endif
  71. //cateId为0时接口无返回,改为空字符串
  72. this.cateId = options.tid ? options.tid : '';
  73. this.keywords = options.keywords ? options.keywords : ''
  74. this.loadData();
  75. },
  76. onPageScroll(e) {
  77. //兼容iOS端下拉时顶部漂移
  78. if (e.scrollTop >= 0) {
  79. this.headerPosition = "fixed";
  80. } else {
  81. this.headerPosition = "absolute";
  82. }
  83. },
  84. //下拉刷新
  85. onPullDownRefresh() {
  86. this.loadData('refresh');
  87. },
  88. //加载更多
  89. onReachBottom() {
  90. this.loadData();
  91. },
  92. methods: {
  93. //加载商品 ,带下拉刷新和上滑加载
  94. async loadData(type = 'add', loading) {
  95. //没有更多直接返回
  96. if (type === 'add') {
  97. if (this.loadingType === 'nomore') {
  98. return;
  99. }
  100. this.loadingType = 'loading';
  101. } else {
  102. this.loadingType = 'more'
  103. }
  104. let orderByInfo = {}
  105. if (this.filterIndex === 0) {
  106. //销量排序
  107. orderByInfo = {
  108. orderBy: 'sales',
  109. isAsc: false
  110. }
  111. }
  112. if (this.filterIndex === 1) {
  113. //价格排序 需要从新获取Page
  114. orderByInfo = {
  115. orderBy: 'price',
  116. isAsc: this.priceOrder === 1
  117. }
  118. }
  119. if (type === 'refresh') {
  120. this.pageNo = 1
  121. }
  122. this.$api.request('get', 'storage/position/getGoodsPageByStorage', {
  123. categoryId: this.cateId,
  124. title: this.keywords,
  125. pageNo: this.pageNo,
  126. storageId: this.$store.state.storageId,
  127. ...orderByInfo
  128. }).then(res => {
  129. let tempList = res.data.rows
  130. if (type === 'refresh') {
  131. this.goodsList = [];
  132. }
  133. this.goodsList = this.goodsList.concat(tempList);
  134. this.pageNo = res.data.pageNo + 1
  135. this.loadingType = res.data.totalPageNo > res.data.pageNo ? 'more' : 'nomore';
  136. if (type === 'refresh') {
  137. if (loading == 1) {
  138. uni.hideLoading()
  139. } else {
  140. uni.stopPullDownRefresh();
  141. }
  142. }
  143. })
  144. },
  145. //筛选点击
  146. tabClick(index) {
  147. if (this.filterIndex === index && index !== 1) {
  148. return;
  149. }
  150. this.filterIndex = index;
  151. if (index === 1) {
  152. this.priceOrder = this.priceOrder === 1 ? 2 : 1;
  153. } else {
  154. this.priceOrder = 0;
  155. }
  156. uni.pageScrollTo({
  157. duration: 300,
  158. scrollTop: 0
  159. })
  160. this.loadData('refresh', 1);
  161. uni.showLoading({
  162. title: '正在加载'
  163. })
  164. },
  165. //详情
  166. navToDetailPage(item) {
  167. //测试数据没有写id,用title代替
  168. let id = item.id;
  169. uni.navigateTo({
  170. url: `/pages/product/detail?id=${id}`
  171. })
  172. },
  173. stopPrevent() {}
  174. },
  175. }
  176. </script>
  177. <style lang="scss">
  178. page,
  179. .content {
  180. background: $page-color-base;
  181. }
  182. .content {
  183. padding-top: 96upx;
  184. }
  185. .navbar {
  186. position: fixed;
  187. left: 0;
  188. top: var(--window-top);
  189. display: flex;
  190. width: 100%;
  191. height: 80upx;
  192. background: #fff;
  193. box-shadow: 0 2upx 10upx rgba(0, 0, 0, .06);
  194. z-index: 10;
  195. .nav-item {
  196. flex: 1;
  197. display: flex;
  198. justify-content: center;
  199. align-items: center;
  200. height: 100%;
  201. font-size: 30upx;
  202. color: $font-color-dark;
  203. position: relative;
  204. &.current {
  205. color: $base-color;
  206. &:after {
  207. content: '';
  208. position: absolute;
  209. left: 50%;
  210. bottom: 0;
  211. transform: translateX(-50%);
  212. width: 120upx;
  213. height: 0;
  214. border-bottom: 4upx solid $base-color;
  215. }
  216. }
  217. }
  218. .p-box {
  219. display: flex;
  220. flex-direction: column;
  221. .yticon {
  222. display: flex;
  223. align-items: center;
  224. justify-content: center;
  225. width: 30upx;
  226. height: 14upx;
  227. line-height: 1;
  228. margin-left: 4upx;
  229. font-size: 26upx;
  230. color: #888;
  231. &.active {
  232. color: $base-color;
  233. }
  234. }
  235. .xia {
  236. transform: scaleY(-1);
  237. }
  238. }
  239. .cate-item {
  240. display: flex;
  241. justify-content: center;
  242. align-items: center;
  243. height: 100%;
  244. width: 80upx;
  245. position: relative;
  246. font-size: 44upx;
  247. &:after {
  248. content: '';
  249. position: absolute;
  250. left: 0;
  251. top: 50%;
  252. transform: translateY(-50%);
  253. border-left: 1px solid #ddd;
  254. width: 0;
  255. height: 36upx;
  256. }
  257. }
  258. }
  259. /* 分类 */
  260. .cate-mask {
  261. position: fixed;
  262. left: 0;
  263. top: var(--window-top);
  264. bottom: 0;
  265. width: 100%;
  266. background: rgba(0, 0, 0, 0);
  267. z-index: 95;
  268. transition: .3s;
  269. .cate-content {
  270. width: 630upx;
  271. height: 100%;
  272. background: #fff;
  273. float: right;
  274. transform: translateX(100%);
  275. transition: .3s;
  276. }
  277. &.none {
  278. display: none;
  279. }
  280. &.show {
  281. background: rgba(0, 0, 0, .4);
  282. .cate-content {
  283. transform: translateX(0);
  284. }
  285. }
  286. }
  287. .cate-list {
  288. display: flex;
  289. flex-direction: column;
  290. height: 100%;
  291. .cate-item {
  292. display: flex;
  293. align-items: center;
  294. height: 90upx;
  295. padding-left: 30upx;
  296. font-size: 28upx;
  297. color: #555;
  298. position: relative;
  299. }
  300. .two {
  301. height: 64upx;
  302. color: #303133;
  303. font-size: 30upx;
  304. background: #f8f8f8;
  305. }
  306. .active {
  307. color: $base-color;
  308. }
  309. }
  310. /* 商品列表 */
  311. .goods-list {
  312. display: flex;
  313. flex-wrap: wrap;
  314. padding: 0 30upx;
  315. background: #fff;
  316. .goods-item {
  317. display: flex;
  318. flex-direction: column;
  319. width: 48%;
  320. padding-bottom: 40upx;
  321. &:nth-child(2n+1) {
  322. margin-right: 4%;
  323. }
  324. }
  325. .image-wrapper {
  326. width: 100%;
  327. height: 330upx;
  328. border-radius: 3px;
  329. overflow: hidden;
  330. image {
  331. width: 100%;
  332. height: 100%;
  333. opacity: 1;
  334. }
  335. }
  336. .title {
  337. font-size: $font-lg;
  338. color: $font-color-dark;
  339. line-height: 80upx;
  340. }
  341. .price-box {
  342. display: flex;
  343. align-items: center;
  344. justify-content: space-between;
  345. padding-right: 10upx;
  346. font-size: 24upx;
  347. color: $font-color-light;
  348. }
  349. .price {
  350. font-size: $font-lg;
  351. color: $uni-color-primary;
  352. line-height: 1;
  353. &:before {
  354. content: '¥';
  355. font-size: 26upx;
  356. }
  357. }
  358. }
  359. </style>