index.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. <template>
  2. <view class="container">
  3. <!-- 搜索框 -->
  4. <search tips="搜索商品" @event="$navTo('pages/search/index')" />
  5. <!-- 分类样式:一级分类(大图) 10 -->
  6. <view class="cate-content" v-if="templet.style == 10 && list.length > 0">
  7. <view class="cate-wrapper cate_style__10">
  8. <scroll-view :scroll-y="true" :style="{ height: `${scrollHeight - 10}px` }">
  9. <view class="cate-item" v-for="(item, index) in list" :key="index"
  10. @click="onTargetGoodsList(item.category_id)">
  11. <image v-if="item.image" mode="widthFix" :src="item.image.preview_url"></image>
  12. </view>
  13. </scroll-view>
  14. </view>
  15. </view>
  16. <!-- 分类样式:一级分类(小图) 11 -->
  17. <view class="cate-content" v-else-if="templet.style == 11 && list.length > 0">
  18. <view class="cate-wrapper cate_style__11">
  19. <scroll-view class="clear" :scroll-y="true" :style="{ height: `${scrollHeight - 10}px` }">
  20. <view class="cate-item" v-for="(item, index) in list" :key="index"
  21. @click="onTargetGoodsList(item.category_id)">
  22. <image v-if="item.image" mode="widthFix" :src="item.image.preview_url"></image>
  23. <text class="f-26">{{ item.name }}</text>
  24. </view>
  25. </scroll-view>
  26. </view>
  27. </view>
  28. <!-- 分类样式:二级分类 20 -->
  29. <view class="cate-content dis-flex" v-else-if="templet.style == 20 && list.length > 0">
  30. <!-- 左侧 一级分类 -->
  31. <scroll-view class="cate-left f-28" :scroll-y="true" :style="{ height: `${scrollHeight}px` }">
  32. <text class="type-nav" :class="{ selected: curIndex == index }" v-for="(item, index) in list" :key="index"
  33. @click="handleSelectNav(index)">{{ item.name }}</text>
  34. </scroll-view>
  35. <!-- 右侧 二级分类 -->
  36. <scroll-view class="cate-right b-f" :scroll-top="scrollTop" :scroll-y="true"
  37. :style="{ height: `${scrollHeight}px` }">
  38. <view v-if="list[curIndex]">
  39. <view class="cate-right-cont">
  40. <view class="cate-two-box">
  41. <view class="cate-cont-box">
  42. <view class="flex-three" v-for="(item, idx) in list[curIndex].children" :key="idx"
  43. @click="onTargetGoodsList(item.category_id)">
  44. <view class="cate-img-padding">
  45. <view v-if="item.image" class="cate-img">
  46. <image class="image" mode="scaleToFill" :src="item.image.preview_url"></image>
  47. </view>
  48. </view>
  49. <text class="name oneline-hide">{{ item.name }}</text>
  50. </view>
  51. </view>
  52. </view>
  53. </view>
  54. </view>
  55. </scroll-view>
  56. </view>
  57. <empty v-if="!list.length" :isLoading="isLoading" />
  58. </view>
  59. </template>
  60. <script>
  61. import { setCartTabBadge } from '@/core/app'
  62. import SettingKeyEnum from '@/common/enum/setting/Key'
  63. import SettingModel from '@/common/model/Setting'
  64. import * as CategoryApi from '@/api/category'
  65. import Search from '@/components/search'
  66. import Empty from '@/components/empty'
  67. // 最后一次刷新时间
  68. let lastRefreshTime;
  69. export default {
  70. components: {
  71. Search,
  72. Empty
  73. },
  74. data() {
  75. return {
  76. // 列表高度
  77. scrollHeight: 0,
  78. // 一级分类:指针
  79. curIndex: 0,
  80. // 内容区竖向滚动条位置
  81. scrollTop: 0,
  82. // 分类列表
  83. list: [],
  84. // 分类模板设置
  85. templet: {},
  86. // 正在加载中
  87. isLoading: true
  88. }
  89. },
  90. /**
  91. * 生命周期函数--监听页面加载
  92. */
  93. onLoad() {
  94. const app = this
  95. // 设置分类列表高度
  96. app.setListHeight()
  97. // 加载页面数据
  98. app.onRefreshPage()
  99. },
  100. /**
  101. * 生命周期函数--监听页面显示
  102. */
  103. onShow() {
  104. // 每间隔5分钟自动刷新一次页面数据
  105. const curTime = new Date().getTime()
  106. if ((curTime - lastRefreshTime) > 5 * 60 * 1000) {
  107. this.onRefreshPage()
  108. }
  109. },
  110. methods: {
  111. // 刷新页面
  112. onRefreshPage() {
  113. // 记录刷新时间
  114. lastRefreshTime = new Date().getTime()
  115. // 获取页面数据
  116. this.getPageData()
  117. // 更新购物车角标
  118. setCartTabBadge()
  119. },
  120. /**
  121. * 获取页面数据
  122. */
  123. getPageData() {
  124. const app = this
  125. app.isLoading = true
  126. Promise.all([
  127. // 获取分类模板设置
  128. // 优化建议: 可以将此处的false改为true 启用缓存
  129. SettingModel.data(false),
  130. // 获取分类列表
  131. CategoryApi.list()
  132. ])
  133. .then(result => {
  134. // 初始化分类模板设置
  135. app.initTemplet(result[0])
  136. // 初始化分类列表数据
  137. app.initCategory(result[1])
  138. })
  139. .finally(() => app.isLoading = false)
  140. },
  141. /**
  142. * 初始化分类模板设置
  143. * @param {Object} result
  144. */
  145. initTemplet(setting) {
  146. this.templet = setting[SettingKeyEnum.PAGE_CATEGORY_TEMPLATE.value]
  147. },
  148. /**
  149. * 初始化分类列表数据
  150. * @param {Object} result
  151. */
  152. initCategory(result) {
  153. const app = this
  154. const data = result.data
  155. app.list = data.list
  156. },
  157. /**
  158. * 设置分类列表高度
  159. */
  160. setListHeight() {
  161. const app = this
  162. uni.getSystemInfo({
  163. success(res) {
  164. app.scrollHeight = res.windowHeight - 47
  165. }
  166. })
  167. },
  168. // 一级分类:选中分类
  169. handleSelectNav(index) {
  170. const app = this
  171. app.curIndex = index
  172. app.scrollTop = 0
  173. },
  174. // 跳转至商品列表页
  175. onTargetGoodsList(categoryId) {
  176. this.$navTo('pages/goods/list', { categoryId })
  177. }
  178. },
  179. /**
  180. * 设置分享内容
  181. */
  182. onShareAppMessage() {
  183. const app = this
  184. return {
  185. title: _this.templet.shareTitle,
  186. path: '/pages/category/index?' + app.$getShareUrlParams()
  187. }
  188. },
  189. /**
  190. * 分享到朋友圈
  191. * 本接口为 Beta 版本,暂只在 Android 平台支持,详见分享到朋友圈 (Beta)
  192. * https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share-timeline.html
  193. */
  194. onShareTimeline() {
  195. const app = this
  196. return {
  197. title: _this.templet.shareTitle,
  198. path: '/pages/category/index?' + app.$getShareUrlParams()
  199. }
  200. }
  201. }
  202. </script>
  203. <style>
  204. page {
  205. background: #fff;
  206. }
  207. </style>
  208. <style lang="scss" scoped>
  209. .cate-content {
  210. background: #fff;
  211. }
  212. .cate-wrapper {
  213. padding: 0 20rpx 20rpx 20rpx;
  214. box-sizing: border-box;
  215. }
  216. /* 一级分类(大图) 10 */
  217. .cate_style__10 .cate-item {
  218. margin-bottom: 18rpx;
  219. }
  220. .cate_style__10 .cate-item:last-child {
  221. margin-bottom: 0;
  222. }
  223. .cate_style__10 .cate-item image {
  224. display: block;
  225. width: 100%;
  226. height: auto;
  227. }
  228. /* 一级分类(小图) 11 */
  229. .cate_style__11 .cate-item {
  230. float: left;
  231. padding: 25rpx;
  232. width: 33.3333%;
  233. text-align: center;
  234. box-sizing: border-box;
  235. }
  236. .cate_style__11 .cate-item image {
  237. /* height: 208.656rpx; */
  238. width: 100%;
  239. display: block;
  240. }
  241. .cate_style__11 .cate-item image {
  242. display: block;
  243. width: 100%;
  244. margin-bottom: 10rpx;
  245. }
  246. .cate_style__11 .cate-item text {
  247. display: block;
  248. color: #555;
  249. }
  250. /* 二级分类 20 */
  251. .cate-content {
  252. width: 100%;
  253. }
  254. .cate-left {
  255. flex-direction: column;
  256. display: flex;
  257. flex: 0 0 23%;
  258. color: #444;
  259. height: 100%;
  260. background: #f8f8f8;
  261. }
  262. .cate-right {
  263. display: flex;
  264. flex-direction: column;
  265. height: 100%;
  266. overflow: hidden;
  267. }
  268. .cate-right-cont {
  269. width: 100%;
  270. display: flex;
  271. flex-flow: row wrap;
  272. align-content: flex-start;
  273. padding-top: 15rpx;
  274. }
  275. .type-nav {
  276. position: relative;
  277. height: 90rpx;
  278. line-height: 90rpx;
  279. text-align: center;
  280. z-index: 10;
  281. display: block;
  282. font-size: 26rpx;
  283. }
  284. .type-nav.selected {
  285. background: #fff;
  286. color: #fa2209;
  287. border-right: none;
  288. font-size: 28rpx;
  289. }
  290. .cate-cont-box {
  291. margin-bottom: 30rpx;
  292. padding-bottom: 10rpx;
  293. background: #fff;
  294. overflow: hidden;
  295. .name {
  296. display: block;
  297. padding-bottom: 30rpx;
  298. text-align: center;
  299. font-size: 26rpx;
  300. color: #444444;
  301. }
  302. .cate-img-padding {
  303. padding: 16rpx 16rpx 4rpx 16rpx;
  304. }
  305. .cate-img {
  306. position: relative;
  307. width: 100%;
  308. padding-top: 100%;
  309. .image {
  310. width: 100%;
  311. height: 100%;
  312. position: absolute;
  313. top: 0;
  314. left: 0;
  315. border-radius: 10rpx;
  316. }
  317. }
  318. }
  319. .cate-two-box {
  320. width: 100%;
  321. padding: 0 10px;
  322. }
  323. </style>