hookehuyr

refactor(Home): 优化步骤箭头显示逻辑,改为内嵌式显示

移除全局跟随箭头逻辑,改为在步骤内直接显示箭头
简化窗口尺寸变化处理,仅更新装饰线位置
调整底部留白以适应新箭头布局
......@@ -64,12 +64,13 @@
<div class="step-content">
<span class="step-text">{{ step.name }}</span>
</div>
<!-- 点击或默认选中后显示在步骤下方的箭头(使用 v-show 减少渲染延迟) -->
<div v-show="arrow_visible && step.active && !step.is_placeholder" class="bottom-arrow">
<img src="https://cdn.ipadbiz.cn/stdj/images/home/%E7%82%B9@2x.png" alt="选中" />
</div>
</div>
</div>
<!-- 全局底部箭头:跟随选中项移动 -->
<div v-show="processSteps.length" class="bottom-arrow moving-arrow" :style="arrowStyle">
<img src="https://cdn.ipadbiz.cn/stdj/images/home/%E7%82%B9@2x.png" alt="选中" />
</div>
</div>
</div>
</div>
......@@ -200,18 +201,19 @@ const videoOptions = ref({
const processSteps = ref([])
// 流程步骤容器引用
const processStepsRef = ref(null)
// 底部箭头的动态样式(保持在容器内,避免被裁剪)
const arrowStyle = ref({ left: '50%', bottom: '0.25rem', transform: 'translateX(-50%)' })
// 底部箭头在不同屏幕下的rem偏移值
const arrowBottomRem = ref(0.25)
/**
* 是否显示箭头
* 说明:默认不显示,用户点击步骤后显示在该步骤下方
* @type {import('vue').Ref<boolean>}
*/
const arrow_visible = ref(false)
/**
* 处理窗口尺寸变化:更新箭头bottom并重新定位箭头
* 处理窗口尺寸变化:仅更新装饰线位置
* @returns {void}
*/
const handleResize = () => {
updateArrowBottomByScreen()
updateArrowPosition()
calculateLinePosition()
}
// 每页显示的步骤数量(移动端要求最多7个)
......@@ -317,7 +319,7 @@ const ensurePageScrollTop = () => {
}
/**
* 点击切换步骤状态并更新底部箭头位置
* 点击切换步骤状态并显示箭头
* @param {number} index 选中步骤索引
*/
const selectStep = (index) => {
......@@ -329,8 +331,8 @@ const selectStep = (index) => {
scrollToPage(pageIndex)
// 切换步骤后重新计算装饰线位置
calculateLinePosition()
// 切换步骤后更新底部箭头位置
updateArrowPosition()
// 用户点击后显示箭头
arrow_visible.value = true
}
/**
......@@ -362,8 +364,7 @@ onMounted(async () => {
el.addEventListener('scroll', dismissSwipeHint, { passive: true })
}
})
// 初始化不同屏幕下箭头bottom适配并监听resize
updateArrowBottomByScreen()
// 监听窗口尺寸变化,仅用于更新装饰线位置
if (typeof window !== 'undefined') {
window.addEventListener('resize', handleResize)
}
......@@ -381,6 +382,8 @@ onMounted(async () => {
category_link: item.category_link || '',
})) || [];
processSteps.value[0].active = true;
// 首次默认选中,立即显示箭头,避免首次点击前不显示
arrow_visible.value = true;
// 三师七证
mastersList.value = list?.STDJSSQZ?.map(item => ({
id: item.id,
......@@ -402,8 +405,6 @@ onMounted(async () => {
// 初始化轮播位置
nextTick(() => {
updateCarouselPosition(false)
// 初始化底部箭头位置
updateArrowPosition()
// 列表内容渲染后再兜底回顶一次,避免外部干扰
ensurePageScrollTop()
})
......@@ -430,7 +431,6 @@ onUnmounted(() => {
// 监听当前步骤变化,重新计算装饰线位置
watch(currentStep, () => {
calculateLinePosition()
updateArrowPosition()
}, { deep: true })
// 查看更多按钮点击事件
......@@ -624,58 +624,7 @@ const handleNewsClick = (item) => {
}
}
/**
* 更新底部箭头的位置,使其移动到当前选中步骤下方
*/
/**
* 更新底部箭头的位置,使其移动到当前选中步骤下方
* @returns {void}
*/
const updateArrowPosition = () => {
const containerEl = processStepsRef.value
if (!containerEl) return
const stepsEls = containerEl.querySelectorAll('.process-step')
const activeIndex = processSteps.value.findIndex(s => s.active)
if (activeIndex < 0 || !stepsEls[activeIndex]) return
const activeEl = stepsEls[activeIndex]
const containerRect = containerEl.getBoundingClientRect()
const activeRect = activeEl.getBoundingClientRect()
// 计算选中项中心点相对容器的left位置
const centerX = activeRect.left + activeRect.width / 2 - containerRect.left
// 使用px进行精确定位(移动端rem布局下,定位需要像素计算)
arrowStyle.value = {
left: `${centerX}px`,
// 不同屏幕下适配底部偏移(rem单位)
bottom: `${arrowBottomRem.value}rem`,
transform: 'translateX(-50%)'
}
}
/**
* 依据屏幕宽度适配箭头bottom值
* 说明:遵循项目rem基准16px,将窗口宽度转换为rem做断点判断
* - ≤30rem(约≤480px):0.25rem
* - ≤48rem(约≤768px):0.3rem
* - >48rem:0.5rem
* @returns {void}
*/
const updateArrowBottomByScreen = () => {
let wRem = 48
if (typeof window !== 'undefined') {
wRem = (window.innerWidth || 768) / 16
}
if (wRem <= 30) {
arrowBottomRem.value = 0
} else if (wRem <= 48) {
arrowBottomRem.value = -0.25
} else {
arrowBottomRem.value = -0.5
}
}
// 原全局跟随箭头逻辑已移除:箭头改为嵌入步骤内,仅在点击后显示
// 是否显示横向滑动提示
const showSwipeHint = ref(true)
......@@ -1109,7 +1058,7 @@ const dismissSwipeHint = () => {
-webkit-overflow-scrolling: touch;
/* 底部留白,确保容器高度包含箭头展示空间 */
padding-top: 0.5rem;
padding-bottom: 1rem;
padding-bottom: 1.5rem;
}
/* 隐藏移动端滚动条以优化视觉 */
......