index.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <!--
  2. * @Author: jmy
  3. * @Date: 2026-01-06 12:02:41
  4. * @LastEditors: Please set LastEditors
  5. * @LastEditTime: 2026-01-06 15:02:20
  6. * @Description: 首页
  7. -->
  8. <template>
  9. <view class="w-all h-all flex flex-column bg-F5F7FA">
  10. <image src="/static/images/yuexuan_home_top_bg.png" class="absolute top-0 left-0 zi-1 w-all h-266"></image>
  11. <uni-nav-bar fixed :statusBar="true" left-icon="back" backgroundColor="" :border="false" rightWidth="0"
  12. leftWidth="0">
  13. <template v-slot:default>
  14. <view class="scs-headr-default flex items-center h-44">
  15. <view class="flex-1">
  16. <view class="fw-500 fs-18 text-000000">芳华悦选</view>
  17. <view class="fw-400 fs-12 text-999999">让家人放心吃健康安全的食品</view>
  18. </view>
  19. <view class="img-car flex items-center justify-center w-32 h-32 bg-white rounded-32">
  20. <image class="w-20 h-20" src="/static/images/shopping_car_icon.png"></image>
  21. </view>
  22. </view>
  23. </template>
  24. </uni-nav-bar>
  25. <!-- 搜索栏 -->
  26. <HomeSearch @onSearch="onSearch" />
  27. <view class="zi-10 flex-1 overflow-auto">
  28. <ScsScrollView ref="fresher" refresherBackground="transparent" :refresherEnabled="false"
  29. @onfresher="onfresher" @loadMore="loadMore" @handleScroll="(flag) => isShowToTop = flag">
  30. <template v-slot:list>
  31. <!-- tab栏 -->
  32. <view class="scs-nav-bar px-12 mt-11 rounded-8">
  33. <view class="flex items-center relative ">
  34. <ScsScrollNavbar :tabsData="tabsData" :tabCurrentIndex="tabCurrentIndex" nameKey="name"
  35. key="tabCurrentIndex" @tabChange="tabChange" />
  36. <image class="w-32 h-32 absolute bottom-2.5 right-40 zi-10"
  37. src="/static/images/white_gradient_bg.png">
  38. </image>
  39. <view class="flex items-center justify-center">
  40. <image class="w-16 h-16 ml-5 mr-12" src="/static/images/product_section_icon.png">
  41. </image>
  42. <image class="w-16 h-16 mr-7" src="/static/images/home_filter_icon.png"></image>
  43. </view>
  44. </view>
  45. <HomeMenu :autoplay="false" :swiperList="menusData" />
  46. </view>
  47. <!-- 商品栏 -->
  48. <HomeProduct />
  49. <!-- tab栏 -->
  50. <view class="tab-goods w-all mt-10 rounded-t-8 px-28">
  51. <ScsScrollNavbar :tabsData="tabsProduct" activeColor="#02B176" textColor="#333333"
  52. :isUseActImg="true" :isScroll="false" :isUseLine="false" :calcLeft="28"
  53. :tabCurrentIndex="tabsProductIndex" nameKey="name" key="tabsProductIndex"
  54. @tabChange="tabProductChange" />
  55. </view>
  56. <!-- 商品列表 -->
  57. <view class="px-12 mt-14">
  58. <HomeGoodsItem />
  59. </view>
  60. <!-- 更多列表 -->
  61. <ScsHelangWaterfall :waterfallList="waterfallList">
  62. <template v-slot:special>
  63. <HomeSalesItem />
  64. </template>
  65. <template v-slot:default="{ item }">
  66. <HomeMoreItem :itemData="item" :itemIndex="index" :key="item.id" />
  67. </template>
  68. </ScsHelangWaterfall>
  69. <u-gap height="15"></u-gap>
  70. </template>
  71. </ScsScrollView>
  72. <ScsScrollTop :isShowToTop="isShowToTop" @goTop="$refs.fresher.goTop" />
  73. </view>
  74. <!-- 频道 可拖拽 -->
  75. <channel ref="channelManager" :initial-my-channels="myChannels" :initial-all-channels="allChannels"
  76. :active-channel-id="activeChannelId" :show="showChannel" @channels-change="onChannelsChange"
  77. @order-change="onOrderChange" @channel-tap="onChannelTap" @close="showChannel = false" />
  78. </view>
  79. </template>
  80. <script>
  81. import HomeMenu from './components/home-menu.vue'
  82. import HomeProduct from './components/home-product.vue'
  83. import HomeSearch from './components/home-search.vue'
  84. import HomeGoodsItem from './components/home-goods-item.vue'
  85. import HomeSalesItem from './components/home-sales.vue'
  86. import HomeMoreItem from './components/home-more-item.vue'
  87. import ScsHelangWaterfall from '@/components/public/scs-helang-waterfall.vue'
  88. import channel from '@/components/channel.vue'
  89. import {
  90. getMenu,
  91. } from '@/api/index'
  92. export default {
  93. components: {
  94. HomeMenu,
  95. HomeProduct,
  96. HomeSearch,
  97. HomeGoodsItem,
  98. HomeSalesItem,
  99. HomeMoreItem,
  100. channel,
  101. ScsHelangWaterfall,
  102. },
  103. data() {
  104. return {
  105. showChannel: false, // 默认不显示
  106. channelManager: false,
  107. // 频道相关数据
  108. activeChannelId: 1,
  109. myChannels: [{
  110. id: 1,
  111. name: '推荐'
  112. },
  113. {
  114. id: 2,
  115. name: '热点'
  116. },
  117. {
  118. id: 3,
  119. name: '科技'
  120. },
  121. {
  122. id: 4,
  123. name: '体育'
  124. }
  125. ],
  126. allChannels: [{
  127. id: 5,
  128. name: '财经'
  129. },
  130. {
  131. id: 6,
  132. name: '娱乐'
  133. },
  134. {
  135. id: 7,
  136. name: '时尚'
  137. },
  138. {
  139. id: 8,
  140. name: '汽车'
  141. },
  142. {
  143. id: 9,
  144. name: '游戏'
  145. },
  146. {
  147. id: 10,
  148. name: '旅游'
  149. }
  150. ],
  151. // UI状态数据
  152. statusBarHeight: 0,
  153. isShowToTop: false,
  154. // Tab数据
  155. tabsData: [{
  156. name: '精选'
  157. },
  158. {
  159. name: '健康新品'
  160. },
  161. {
  162. name: '营养保健'
  163. },
  164. {
  165. name: '健康滋补'
  166. },
  167. ],
  168. tabCurrentIndex: 0,
  169. tabsProduct: [{
  170. name: '今日主推'
  171. },
  172. {
  173. name: '健康新品'
  174. },
  175. {
  176. name: '营养保健'
  177. },
  178. ],
  179. menusData: [],
  180. tabsProduct: [
  181. { name: '今日主推' },
  182. { name: '健康新品' },
  183. { name: '营养保健' },
  184. ],
  185. tabsProductIndex: 0,
  186. goodList: [1, 2],
  187. isShowToTop: false,
  188. waterfallList: [
  189. {
  190. id: 2,
  191. image: 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422',
  192. title: '云南白药EGER每瓶重50g保险液每测试',
  193. },
  194. {
  195. id: 3,
  196. image: 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422',
  197. title: '云南白药EGER每瓶重50g保险液每测试',
  198. },
  199. {
  200. id: 4,
  201. image: 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422',
  202. title: '云南白药EGER每瓶重50g保险液每测试',
  203. },
  204. {
  205. id: 5,
  206. image: 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422',
  207. title: '云南白药EGER每瓶重50g保险液每测试',
  208. },
  209. {
  210. id: 4,
  211. image: 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422',
  212. title: '云南白药EGER每瓶重50g保险液每测试',
  213. },
  214. {
  215. id: 5,
  216. image: 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422',
  217. title: '云南白药EGER每瓶重50g保险液每测试',
  218. }],
  219. }
  220. },
  221. onLoad() {
  222. },
  223. onShow() {
  224. this.getMenuData();
  225. },
  226. methods: {
  227. // 搜索
  228. onSearch(keyword) {
  229. },
  230. showChannelPopup() {
  231. this.showChannel = true;
  232. },
  233. // 在某个地方调用这个方法,比如点击按钮
  234. onSomeButtonClick() {
  235. this.showChannelPopup();
  236. },
  237. // 搜索事件
  238. onSearch(keyword) {
  239. console.log('搜索关键词:', keyword);
  240. // 实现搜索逻辑
  241. },
  242. // 分类tab切换
  243. tabChange(index) {
  244. this.tabCurrentIndex = index;
  245. // 这里可以添加分类切换后的数据加载逻辑
  246. },
  247. // 商品tab切换
  248. tabProductChange(index) {
  249. this.tabsProductIndex = index;
  250. // 这里可以添加商品分类切换后的数据加载逻辑
  251. },
  252. // 获取分类数据
  253. async getMenuData() {
  254. try {
  255. const {
  256. code,
  257. data,
  258. msg
  259. } = await getMenu();
  260. if (code == 200) {
  261. // 将数据每5个一组分割
  262. this.menusData = this.$scsUtils.splitArrayIntoSubarrays(data, 5) || []
  263. } else {
  264. uni.showToast({
  265. title: msg,
  266. icon: 'none'
  267. })
  268. }
  269. } catch (error) {
  270. console.error('获取菜单数据失败:', error);
  271. uni.showToast({
  272. title: '网络错误,请重试',
  273. icon: 'none'
  274. })
  275. }
  276. },
  277. // 下拉刷新
  278. onfresher() {
  279. const self = this;
  280. self.$refs.fresher.isTrigger = true;
  281. // 模拟异步请求
  282. setTimeout(() => {
  283. self.$refs.fresher.refresherText = "刷新成功";
  284. self.$refs.fresher.isTrigger = false;
  285. // 这里可以添加实际的数据刷新逻辑
  286. }, 500);
  287. },
  288. // 上拉加载更多
  289. loadMore() {
  290. // 实现加载更多逻辑
  291. console.log('加载更多数据');
  292. },
  293. // 频道相关方法
  294. onChannelsChange(channels) {
  295. console.log('频道变化:', channels);
  296. // 处理频道变化
  297. },
  298. onOrderChange(orderInfo) {
  299. console.log('顺序变化:', orderInfo);
  300. // 处理顺序变化
  301. },
  302. onChannelTap(channel) {
  303. console.log('点击频道:', channel);
  304. this.activeChannelId = channel.id;
  305. // 根据频道切换内容
  306. },
  307. }
  308. }
  309. </script>
  310. <style lang="scss" scoped>
  311. ::v-deep.scs-nav-bar {
  312. background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 49.52%, #F5F7FA 100%);
  313. .scs-scroll-navbar {
  314. width: calc(100vw - 140rpx) !important;
  315. .nav-underline {
  316. background: linear-gradient(90deg, rgba(56, 217, 125, 0.5) 0%, rgba(56, 217, 125, 0) 100%);
  317. bottom: 28rpx;
  318. }
  319. }
  320. }
  321. ::v-deep .tab-goods {
  322. background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 49.52%, #F5F7FA 100%);
  323. .scs-scroll-navbar {
  324. .nav-item {
  325. margin-right: 78rpx !important;
  326. }
  327. }
  328. }
  329. </style>