Jacob
2026-10-14 c5c8af3b41faad94be35e88dd65d418cefb83b1e
pages/goods_cate/goods_cate.vue
....@@ -144,7 +144,11 @@
144144 totalGetNum: 0,
145145 // 首屏优化:当前分类的待完成请求数
146146 catePending: [],
147
+ // 标记各分类是否已派发过请求,避免切换分类时重复请求
148
+ cateStarted: [],
147149 firstScreenReady: true,
150
+ // 后台加载标记:首屏渲染并关闭loading后,才开始后台加载其余分类
151
+ bgLoaded: false,
148152 // 渲染优化:非首屏分类数据缓冲队列,批量渲染减少setData次数
149153 deferredLists: [],
150154 deferTimer: null,
....@@ -162,6 +166,8 @@
162166 let that = this;
163167 that.menuTop = uni.getMenuButtonBoundingClientRect().top;
164168 that.menuHeight = uni.getMenuButtonBoundingClientRect().height;
169
+ // 尽早计算页面布局高度,避免首屏数据就绪后因 height 为 0 而白屏
170
+ that.infoScroll();
165171 if (that.$store.getters.careBeanRate) {
166172 that.$nextTick(() => {
167173 that.$set(that, 'careBeanRate', that.$store.getters.careBeanRate)
....@@ -176,6 +182,10 @@
176182 });
177183 },
178184 mounted() {},
185
+ onReady() {
186
+ // 页面渲染完成后复核一次布局尺寸(含滚动区域 scrollHeight)
187
+ this.infoScroll();
188
+ },
179189 onHide() {
180190 let that = this;
181191 if (that.$store.getters.isSystemHide) {
....@@ -339,6 +349,10 @@
339349 that.isClicking = true;
340350 that.navActive = index;
341351 that.subActive = 0;
352
+ // loading期间切到尚未发起请求的分类时,立即补发请求,避免loading卡住
353
+ if (!that.cateStarted[index]) {
354
+ that.loadCateByIndex(index);
355
+ }
342356 // loading期间切换分类,若目标分类已加载完成则立即关闭loading
343357 that.checkFirstScreen(index);
344358 that.$nextTick(() => {
....@@ -352,6 +366,10 @@
352366 let that = this;
353367 that.isClicking = true;
354368 that.subActive = index;
369
+ // 当前分类尚未发起请求时补发,避免loading卡住
370
+ if (!that.cateStarted[that.navActive]) {
371
+ that.loadCateByIndex(that.navActive);
372
+ }
355373 that.checkFirstScreen(that.navActive);
356374 that.$nextTick(() => {
357375 that.scrollIntoView = 'list' + that.navActive + '_' + that.subActive;
....@@ -391,21 +409,28 @@
391409 let that = this;
392410 that.firstScreenReady = false;
393411 that.allRequestsDone = false;
412
+ that.bgLoaded = false;
394413 that.deferredLists = [];
395414 if (that.deferTimer) {
396415 clearTimeout(that.deferTimer);
397416 that.deferTimer = null;
398417 }
418
+ // 暂不考虑传入cid的情况:一律从第一个分类开始加载首屏
419
+ that.navActive = 0;
420
+ that.subActive = 0;
399421 uni.showLoading();
400422 getCategoryList().then(res => {
401
- that.categoryList = res.data;
423
+ that.categoryList = res.data || [];
402424 // 重置计数,避免重复进入页面时累积
403425 that.totalGetNum = 0;
404426 that.finishNum = 0;
405427 that.catePending = [];
428
+ that.cateStarted = [];
406429 that.categoryList.forEach((item, index) => {
407
-
408430 if (item.child && item.child.length > 0) {
431
+ item.child.sort((a, b) => {
432
+ return a.sort - b.sort;
433
+ });
409434 that.totalGetNum += item.child.length;
410435 that.catePending[index] = item.child.length;
411436 } else {
....@@ -413,45 +438,46 @@
413438 that.catePending[index] = 1;
414439 }
415440 })
416
-
417
- // 先标记当前选中分类,再发起请求
418
- that.categoryList.forEach((item, index) => {
419
- if (that.optionId && that.optionId == item.id) {
420
- that.navActive = index;
421
- that.subActive = 0;
422
- }
423
- if (item.child && item.child.length > 0) {
424
- item.child.sort((a, b) => {
425
- return a.sort - b.sort;
426
- });
427
- item.child.forEach((item2, index2) => {
428
- if (that.optionId && that.optionId == item2.id) {
429
- that.navActive = index;
430
- that.subActive = index2;
431
- }
432
- })
433
- }
441
+ // 分类为空时直接关闭loading,避免一直停留在loading态
442
+ if (!that.categoryList.length) {
443
+ that.firstScreenReady = true;
444
+ that.isLoading = false;
445
+ uni.hideLoading();
446
+ return;
447
+ }
448
+ // 首屏优化:先只请求第一个分类,保证首屏数据最快返回并直接渲染
449
+ that.loadCateByIndex(that.navActive);
450
+ // 其余分类待首屏渲染、loading关闭后,由 loadRestCategory 后台错峰加载
451
+ })
452
+ },
453
+ // 按索引加载某个分类下的商品数据(同一分类只派发一次)
454
+ loadCateByIndex(index) {
455
+ let that = this;
456
+ let item = that.categoryList[index];
457
+ if (!item) return;
458
+ if (that.cateStarted[index]) return;
459
+ that.cateStarted[index] = true;
460
+ if (item.child && item.child.length > 0) {
461
+ item.child.forEach((item2, index2) => {
462
+ that.getAllProductList('isSub', index, index2);
434463 })
435
-
436
- const loadCate = (index) => {
437
- let item = that.categoryList[index];
438
- if (item.child && item.child.length > 0) {
439
- item.child.forEach((item2, index2) => {
440
- that.getAllProductList('isSub', index, index2);
441
- })
442
- } else {
443
- that.getAllProductList(false, index);
444
- }
445
- };
446
- // 当前分类优先请求,保证首屏数据最先返回
447
- loadCate(that.navActive);
448
- that.categoryList.forEach((item, index) => {
449
- if (index != that.navActive) {
450
- loadCate(index);
451
- }
452
- })
453
-
454
-
464
+ } else {
465
+ that.getAllProductList(false, index);
466
+ }
467
+ },
468
+ // 首屏渲染并关闭loading后,后台错峰加载其余分类,避免与首屏抢请求/抢渲染
469
+ loadRestCategory() {
470
+ let that = this;
471
+ if (that.bgLoaded) return;
472
+ that.bgLoaded = true;
473
+ let delay = 0;
474
+ that.categoryList.forEach((item, index) => {
475
+ if (index == that.navActive) return;
476
+ // 每个分类错开触发,逐步在后台铺开,避免一次性铺满请求队列
477
+ delay += 50;
478
+ setTimeout(() => {
479
+ that.loadCateByIndex(index);
480
+ }, delay);
455481 })
456482 },
457483 // 当前分类数据全部就绪后立即关闭全屏loading,不必等待所有分类
....@@ -465,6 +491,8 @@
465491 that.$nextTick(() => {
466492 setTimeout(() => {
467493 uni.hideLoading();
494
+ // 首屏已渲染且loading已关闭,此时才开始后台加载其余分类
495
+ that.loadRestCategory();
468496 }, 50)
469497 })
470498 }
....@@ -534,7 +562,8 @@
534562 updateDimensions() {
535563 const query = uni.createSelectorQuery().in(this);
536564 query.select('.goodlistScroll').boundingClientRect(data => {
537
- this.scrollHeight = data.height;
565
+ // 首屏渲染前该节点可能还不存在,避免报错
566
+ if (data) this.scrollHeight = data.height;
538567 }).exec();
539568 },
540569 handleScroll(e) {