feat: 样式调整

This commit is contained in:
liulong 2026-06-05 13:50:47 +08:00
parent 68bc750604
commit cd03f0fa3d
5 changed files with 83 additions and 98 deletions

View File

@ -726,9 +726,21 @@ export default {
this.$nextTick(() => this.scrollListContentToTop());
return true;
}
// anchor :, observer ,
// activeTabIndex 0 tab
this.activeTabIndex = tabIndex;
this.suppressSectionObserver = true;
this.initScrollSpy();
this.initSidebarSticky();
this.scrollToSection(anchor, tabIndex);
// : 1 gxnlpt-block ,
// 2 layout// DOM,
// getBoundingClientRect ""
const jumpToAnchor = () => {
this.scrollToSection(anchor, tabIndex, { behavior: 'auto' });
// observer,
this.suppressSectionObserver = false;
};
requestAnimationFrame(() => requestAnimationFrame(jumpToAnchor));
return true;
},
getIconUrl(iconName) {
@ -993,11 +1005,15 @@ export default {
this.activeTabIndex = tabIndex;
}
},
scheduleScrollUnlock(tabIndex) {
scheduleScrollUnlock(tabIndex, options = {}) {
this.clearScrollUnlock();
this.suppressSectionObserver = true;
this.activeTabIndex = tabIndex;
// : 900ms /scrollend ,
// ( navigateToRouteAnchor)
if (options.skipObserverLock) return;
const scrollRoot = this.getScrollRoot();
let unlocked = false;
const done = () => {
@ -1156,7 +1172,7 @@ export default {
* 通过 getBoundingClientRect 获取目标元素在视口内的视觉位置
* 反算至滚动容器布局坐标后 scrollTo不受 scale 变换影响
*/
scrollToSection(sectionId, tabIndex) {
scrollToSection(sectionId, tabIndex, options = {}) {
const el = document.getElementById(sectionId);
const scrollRoot = this.getScrollRoot();
if (!el || !scrollRoot) return;
@ -1175,8 +1191,12 @@ export default {
const OFFSET_DP = 88; // 稿
const target = Math.max(0, layoutTarget - OFFSET_DP);
scrollRoot.scrollTo({ top: target, behavior: 'smooth' });
this.scheduleScrollUnlock(tabIndex);
// smooth();
// anchor ,使 'auto' ,
// activeTabIndex observer ""
const behavior = options.behavior || 'smooth';
scrollRoot.scrollTo({ top: target, behavior });
this.scheduleScrollUnlock(tabIndex, { skipObserverLock: behavior === 'auto' });
},
/* ========== IntersectionObserver 驱动的 ScrollSpy ========== */
/**

View File

@ -787,10 +787,10 @@ export default {
},
//
handleOverseasClick(item) {
if (item && item.comingSoon) {
this.showComingSoon('航运燃料专题');
return;
}
// if (item && item.comingSoon) {
// this.showComingSoon('');
// return;
// }
if (!item || !item.sectionId) {
this.$router.push('/qych');
return;

View File

@ -1,11 +1,7 @@
<template>
<div class="hydt-page portal-page portal-page-shell">
<!-- Figma banner-bg 150622:19115背景 imageRef ec2e3dd -->
<section
class="hydt-banner"
:class="{ 'hydt-banner--collapsed': bannerCollapsed }"
aria-label="行业动态"
>
<section class="hydt-banner" aria-label="行业动态">
<div class="hydt-banner-bg" aria-hidden="true"></div>
<div class="hydt-banner-inner page-content-wrap">
<p class="hydt-breadcrumb">
@ -27,7 +23,7 @@
<section class="hydt-body">
<div class="hydt-body-inner page-content-wrap">
<div class="hydt-panel">
<div class="hydt-tabs" role="tablist" aria-label="动态分类">
<div ref="tabsRef" class="hydt-tabs" role="tablist" aria-label="动态分类">
<button
v-for="(tab, index) in newsTabs"
:key="tab.type"
@ -45,7 +41,7 @@
<div v-if="pageLoading" class="hydt-state">加载中...</div>
<div v-else-if="!filteredList.length" class="hydt-state">暂无相关动态</div>
<template v-else>
<div class="hydt-list">
<div ref="listRef" class="hydt-list">
<article
v-for="(item, index) in paginatedList"
:key="item.id || item.uuid || item.bt || index"
@ -105,8 +101,6 @@ export default {
newsTabs: NEWS_TABS,
activeTab: 0,
pageLoading: false,
/* 优化需求:点击 tab 后 banner 收起首页进入不收起tab 切换时收起 */
bannerCollapsed: false,
newsListByType: {
gjzc: [],
hyzx: [],
@ -140,22 +134,10 @@ export default {
activeTab() {
this.page.pageNo = 1;
},
// / Figma .content-wrap
'$route.path'() {
this.unbindScrollListener();
this.$nextTick(() => this.bindScrollListener());
},
},
mounted() {
this.syncTabFromRoute(this.$route.query.type);
this.fetchNewsData();
// main.vue .content-wrapwindow
this.$nextTick(() => {
this.bindScrollListener();
});
},
beforeDestroy() {
this.unbindScrollListener();
},
methods: {
goHomeToNews() {
@ -170,28 +152,42 @@ export default {
// tab no-op
if (this.activeTab === index) return;
this.activeTab = index;
// banner banner
// $router.replace main.vue $route.watch
// .content-wrap.scrollTop 0""
// list sticky tabs
//
this.$nextTick(() => {
this.bannerCollapsed = true;
this.scrollToListTop();
});
},
onPageChange() {
const root = this.getScrollRoot();
if (root && root !== window) {
root.scrollTo({ top: 0, behavior: 'smooth' });
} else {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
// list
this.$nextTick(() => {
this.scrollToListTop();
});
},
onScroll() {
// banner banner
if (!this.bannerCollapsed) return;
/**
* 滚动到 list 顶部
*
* 注意点.hydt-tabs position: sticky; top: 0;
* 如果直接把 list 顶端对齐到视口顶会被 sticky tabs 遮住一部分
* 所以目标 top "减去"tabs 的实际高度动态读取避免硬编码样式变量
*/
scrollToListTop() {
const list = this.$refs.listRef;
if (!list) return;
const tabs = this.$refs.tabsRef;
// tabs padding 0
const tabsHeight = tabs ? tabs.getBoundingClientRect().height : 0;
const root = this.getScrollRoot();
const scrollTop = root === window ? window.scrollY : (root && root.scrollTop) || 0;
if (scrollTop <= 8) {
this.bannerCollapsed = false;
const rootRect = root === window ? { top: 0 } : root.getBoundingClientRect();
// list tabs
const targetTop = (root === window ? window.scrollY : root.scrollTop)
+ (list.getBoundingClientRect().top - rootRect.top)
- tabsHeight;
const finalTop = Math.max(0, targetTop);
if (root === window) {
window.scrollTo({ top: finalTop, behavior: 'smooth' });
} else {
root.scrollTo({ top: finalTop, behavior: 'smooth' });
}
},
getScrollRoot() {
@ -200,28 +196,6 @@ export default {
if (portalRoot) return portalRoot;
return window;
},
bindScrollListener() {
// .content-wrap
// window window onScroll
this.unbindScrollListener();
const root = this.getScrollRoot();
if (!root || root === window) {
this._scrollTarget = window;
window.addEventListener('scroll', this.onScroll, { passive: true });
} else {
this._scrollTarget = root;
root.addEventListener('scroll', this.onScroll, { passive: true });
}
},
unbindScrollListener() {
if (!this._scrollTarget) {
// 使 _scrollTarget window
window.removeEventListener('scroll', this.onScroll);
return;
}
this._scrollTarget.removeEventListener('scroll', this.onScroll);
this._scrollTarget = null;
},
handleNewsClick(item) {
const link = item.yyLj || item.lj;
if (link) {
@ -289,12 +263,6 @@ export default {
overflow: hidden;
background: @home-color-page-bg;
box-sizing: border-box;
transition: height 0.45s cubic-bezier(0.4, 0, 0.2, 1), margin-bottom 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 优化需求:点击 tab 后 banner 收起,仅保留扁平标题条 */
.hydt-banner--collapsed {
height: 88px;
}
/* Figma 150622:19115 画框背景 FILL1440×350 */
@ -319,19 +287,6 @@ export default {
padding-top: @hydt-banner-pad-top;
padding-bottom: @hydt-banner-pad-bottom;
box-sizing: border-box;
transition: gap 0.35s ease, padding 0.35s ease;
}
.hydt-banner--collapsed .hydt-banner-inner {
gap: 6px;
padding-top: 18px;
padding-bottom: 18px;
justify-content: center;
}
.hydt-banner--collapsed .hydt-banner-title {
font-size: 22px;
padding: 0;
}
.hydt-breadcrumb {
@ -391,7 +346,7 @@ export default {
}
.hydt-body-inner {
padding: @hydt-body-pad-top 0 @hydt-body-pad-bottom;
padding: 24px 0 @hydt-body-pad-bottom;
box-sizing: border-box;
}
@ -407,7 +362,10 @@ export default {
flex-wrap: wrap;
align-items: flex-end;
gap: @home-news-tab-gap;
margin-bottom: @hydt-tabs-to-list-gap;
padding: @hydt-tabs-to-list-gap 4px;
position: sticky;
top: 0;
background: white;
}
.hydt-tab {
@ -450,6 +408,7 @@ export default {
display: flex;
flex-direction: column;
gap: @hydt-list-gap;
padding: 0 4px;
}
.hydt-item {

View File

@ -44,12 +44,13 @@
<script>
import { mapState } from 'vuex';
import portalFigmaScaleMixin from '@/pages/index/utils/portal-figma-scale-mixin';
// 线 mixin
import comingSoonMixin from '@/pages/index/utils/coming-soon-mixin';
// 线main.vue t-dialog 线
import '@/pages/index/utils/coming-soon-dialog.js';
export default {
name: 'hyzt',
mixins: [portalFigmaScaleMixin],
mixins: [portalFigmaScaleMixin, comingSoonMixin],
components: {},
data() {
return {
@ -66,14 +67,10 @@ export default {
goToHref(href) {
if (href) {
window.open(href, '_blank');
} else if (typeof this.$showComingSoon === 'function') {
//
this.$showComingSoon('航运燃料专题');
} else {
// 退便
// eslint-disable-next-line no-alert
alert('航运燃料专题:敬请期待');
return;
}
// home2 使 mixin ""
this.showComingSoon();
},
},
};

View File

@ -324,6 +324,15 @@ export default {
this.scrollToSectionFromQuery();
});
},
watch: {
// section
// query mounted
'$route.query.section': {
handler() {
this.scrollToSectionFromQuery();
},
},
},
methods: {
goPage(url) {
if (url) {