From fd2579fb5de7168afed579d7f8b74d849316e44e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=86=AF=E8=BE=89?= <13935151924@163.com>
Date: Wed, 19 Nov 2025 13:02:40 +0800
Subject: [PATCH] =?UTF-8?q?=E7=AE=80=E5=8E=86=E5=88=B6=E4=BD=9C111?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
components/AppLayout/AppLayout.vue | 10 +
.../expected-station/expected-station.vue | 210 +++++++++++-------
components/selectJobs/selectJobs.vue | 1 +
packageA/pages/post/post.vue | 13 ++
4 files changed, 149 insertions(+), 85 deletions(-)
diff --git a/components/AppLayout/AppLayout.vue b/components/AppLayout/AppLayout.vue
index c439a44..a6b4af7 100644
--- a/components/AppLayout/AppLayout.vue
+++ b/components/AppLayout/AppLayout.vue
@@ -90,6 +90,10 @@ const handleScrollToLower = () => {
width: 100vw;
height: calc(100% - var(--window-bottom));
overflow: hidden;
+ /* H5环境安全区域适配 */
+ /* #ifdef H5 */
+ height: 100vh;
+ /* #endif */
}
.app-container {
// background-image: url('@/static/icon/background2.png');
@@ -140,7 +144,13 @@ const handleScrollToLower = () => {
.container-main {
flex: 1;
overflow: hidden;
+ padding-bottom: 20rpx;
}
+/* #ifdef H5 */
+.container-main {
+ padding-bottom: 120rpx!important;
+}
+/* #endif */
.main-scroll {
width: 100%;
diff --git a/components/expected-station/expected-station.vue b/components/expected-station/expected-station.vue
index f6e3ce0..40d846b 100644
--- a/components/expected-station/expected-station.vue
+++ b/components/expected-station/expected-station.vue
@@ -25,7 +25,6 @@
@scroll="scrollTopBack"
:scroll-y="true"
class="sex-content-right"
- @wheel="handleWheel"
>
{{ item.label }}
@@ -58,6 +57,8 @@ export default {
stationCateLog: 0,
copyTree: [],
scrollTop: 0,
+ scrollTimer: null,
+ lastScrollTime: 0,
};
},
props: {
@@ -90,109 +91,131 @@ export default {
}
},
},
+ beforeDestroy() {
+ // 组件销毁前清除定时器
+ if (this.scrollTimer) {
+ clearTimeout(this.scrollTimer);
+ this.scrollTimer = null;
+ }
+ },
methods: {
changeStationLog(item) {
this.leftValue = item;
this.rightValue = item.children;
this.scrollTop = 0;
- // 确保左侧列表滚动到正确位置,让当前选中的标签可见
- this.$nextTick(() => {
+ // 使用更激进的防抖策略,避免频繁的左侧滚动
+ if (this.scrollTimer) {
+ clearTimeout(this.scrollTimer);
+ }
+
+ this.scrollTimer = setTimeout(() => {
+ // 确保左侧列表滚动到正确位置,让当前选中的标签可见
const index = this.copyTree.findIndex(i => i.id === item.id);
if (index !== -1 && this.$refs.leftScroll) {
- // 计算需要滚动的距离(每个选项高度约160rpx)
- const scrollTop = index * 160;
+ const itemHeight = 160; // 每个选项高度
+ const visibleHeight = 4 * itemHeight; // 可见区域高度
- // 获取左侧列表的可见高度(假设可见区域能显示约3-4个选项)
- const visibleHeight = 4 * 160; // 约4个选项的高度
+ // 计算目标位置
+ const targetTop = index * itemHeight;
- // 确保选中的标签在可见区域内
- let targetScrollTop = scrollTop;
+ // 获取当前左侧列表的滚动位置
+ const currentLeftScrollTop = this.$refs.leftScroll.scrollTop || 0;
- // 如果选中的标签在底部,确保它不会滚动出可见区域
- if (scrollTop > this.$refs.leftScroll.scrollHeight - visibleHeight) {
- targetScrollTop = Math.max(0, this.$refs.leftScroll.scrollHeight - visibleHeight);
+ // 只有当目标位置不在当前可见区域内时才滚动
+ if (targetTop < currentLeftScrollTop || targetTop > currentLeftScrollTop + visibleHeight - itemHeight) {
+ let targetScrollTop = targetTop;
+
+ // 如果选中的标签在底部,确保它不会滚动出可见区域
+ if (targetTop > this.$refs.leftScroll.scrollHeight - visibleHeight) {
+ targetScrollTop = Math.max(0, this.$refs.leftScroll.scrollHeight - visibleHeight);
+ }
+
+ this.$refs.leftScroll.scrollTo({
+ top: targetScrollTop,
+ duration: 100 // 进一步减少滚动动画时间
+ });
}
-
- this.$refs.leftScroll.scrollTo({
- top: targetScrollTop,
- duration: 300
- });
}
- });
+ }, 100);
},
scrollTopBack(e) {
- this.scrollTop = e.detail.scrollTop;
+ const currentTime = Date.now();
- // 滚动时自动选中对应的左侧标签
- const scrollTop = e.detail.scrollTop;
- let currentSection = null;
- let minDistance = Infinity;
-
- // 遍历所有右侧的二级标题,找到当前最接近顶部的那个
- this.rightValue.forEach((section, index) => {
- // 估算每个section的位置(假设每个section高度大约为 200rpx)
- const sectionTop = index * 200;
- const distance = Math.abs(sectionTop - scrollTop);
-
- if (distance < minDistance) {
- minDistance = distance;
- currentSection = section;
- }
- });
-
- // 如果找到了对应的section,并且不是当前选中的左侧标签,则切换左侧标签
- if (currentSection && this.leftValue.id !== currentSection.parentId) {
- const parentItem = this.copyTree.find(item => item.id === currentSection.parentId);
- if (parentItem) {
- this.leftValue = parentItem;
-
- // 确保左侧列表滚动到正确位置,让当前选中的标签可见
- this.$nextTick(() => {
- const index = this.copyTree.findIndex(i => i.id === parentItem.id);
- if (index !== -1 && this.$refs.leftScroll) {
- // 计算需要滚动的距离(每个选项高度约160rpx)
- const scrollTop = index * 160;
-
- // 获取左侧列表的可见高度(假设可见区域能显示约3-4个选项)
- const visibleHeight = 4 * 160; // 约4个选项的高度
-
- // 确保选中的标签在可见区域内
- let targetScrollTop = scrollTop;
-
- // 如果选中的标签在底部,确保它不会滚动出可见区域
- if (scrollTop > this.$refs.leftScroll.scrollHeight - visibleHeight) {
- targetScrollTop = Math.max(0, this.$refs.leftScroll.scrollHeight - visibleHeight);
- }
-
- this.$refs.leftScroll.scrollTo({
- top: targetScrollTop,
- duration: 300
- });
- }
- });
- }
+ // 更严格的防抖处理:如果距离上次滚动时间太短,则跳过处理
+ if (currentTime - this.lastScrollTime < 80) {
+ return;
}
- },
- handleWheel(e) {
- // 处理鼠标滚轮事件,让右侧内容可以滚动
- e.preventDefault();
- const delta = e.deltaY || e.wheelDelta;
+ this.lastScrollTime = currentTime;
- // 更平滑的滚动,根据滚轮速度调整滚动量
- const scrollAmount = Math.abs(delta) > 100 ? 80 : 40;
- const direction = delta > 0 ? 1 : -1;
+ // 清除之前的定时器
+ if (this.scrollTimer) {
+ clearTimeout(this.scrollTimer);
+ }
- // 更新scrollTop来模拟滚动
- this.scrollTop += scrollAmount * direction;
-
- // 确保scrollTop在合理范围内
- this.scrollTop = Math.max(0, this.scrollTop);
-
- // 触发scroll事件来更新左侧标签选中状态
- this.$nextTick(() => {
- this.scrollTopBack({ detail: { scrollTop: this.scrollTop } });
- });
+ // 设置新的定时器,延迟处理滚动事件
+ this.scrollTimer = setTimeout(() => {
+ this.scrollTop = e.detail.scrollTop;
+
+ // 滚动时自动选中对应的左侧标签
+ const scrollTop = e.detail.scrollTop;
+ let currentSection = null;
+ let minDistance = Infinity;
+
+ // 遍历所有右侧的二级标题,找到当前最接近顶部的那个
+ this.rightValue.forEach((section, index) => {
+ // 更精确地估算每个section的位置(考虑标题高度和内容高度)
+ const sectionTop = index * 280; // 增加估算高度,避免过于敏感
+ const distance = Math.abs(sectionTop - scrollTop);
+
+ if (distance < minDistance) {
+ minDistance = distance;
+ currentSection = section;
+ }
+ });
+
+ // 只有当距离足够近时才切换左侧标签,避免过于敏感
+ if (currentSection && minDistance < 100 && this.leftValue.id !== currentSection.parentId) {
+ const parentItem = this.copyTree.find(item => item.id === currentSection.parentId);
+ if (parentItem) {
+ this.leftValue = parentItem;
+
+ // 使用更激进的防抖策略,避免频繁的左侧滚动
+ if (this.scrollTimer) {
+ clearTimeout(this.scrollTimer);
+ }
+
+ this.scrollTimer = setTimeout(() => {
+ // 只在必要时滚动左侧列表,避免频繁滚动导致的抖动
+ const index = this.copyTree.findIndex(i => i.id === parentItem.id);
+ if (index !== -1 && this.$refs.leftScroll) {
+ // 获取当前左侧列表的滚动位置
+ const currentLeftScrollTop = this.$refs.leftScroll.scrollTop || 0;
+ const itemHeight = 160; // 每个选项高度
+ const visibleHeight = 4 * itemHeight; // 可见区域高度
+
+ // 计算目标位置
+ const targetTop = index * itemHeight;
+
+ // 只有当目标位置不在当前可见区域内时才滚动
+ if (targetTop < currentLeftScrollTop || targetTop > currentLeftScrollTop + visibleHeight - itemHeight) {
+ let targetScrollTop = targetTop;
+
+ // 如果选中的标签在底部,确保它不会滚动出可见区域
+ if (targetTop > this.$refs.leftScroll.scrollHeight - visibleHeight) {
+ targetScrollTop = Math.max(0, this.$refs.leftScroll.scrollHeight - visibleHeight);
+ }
+
+ this.$refs.leftScroll.scrollTo({
+ top: targetScrollTop,
+ duration: 100 // 进一步减少滚动动画时间
+ });
+ }
+ }
+ }, 150); // 增加延迟,避免滚动冲突
+ }
+ }
+ }, 80); // 增加防抖延迟到80ms
},
addItem(item) {
let titiles = [];
@@ -285,6 +308,10 @@ export default {
.sex-content-left
width: 198rpx;
padding: 20rpx 0 0 0;
+ /* 添加硬件加速优化 */
+ transform: translateZ(0);
+ -webkit-transform: translateZ(0);
+ will-change: transform;
.left-list-btn
padding: 0 40rpx 0 24rpx;
display: grid;
@@ -295,6 +322,9 @@ export default {
font-size: 28rpx;
position: relative
margin-top: 60rpx
+ /* 优化渲染性能 */
+ transform: translateZ(0);
+ -webkit-transform: translateZ(0);
.left-list-btn:first-child
margin-top: 0
// .positionNum
@@ -323,6 +353,10 @@ export default {
// border-left: 2px solid #D9D9D9;
background: #F6F6F6;
flex: 1;
+ /* 添加硬件加速优化 */
+ transform: translateZ(0);
+ -webkit-transform: translateZ(0);
+ will-change: transform;
.grid-sex
display: grid;
grid-template-columns: 50% 50%;
@@ -340,6 +374,9 @@ export default {
margin-top: 30rpx;
background: #E8EAEE;
color: #606060;
+ /* 优化渲染性能 */
+ transform: translateZ(0);
+ -webkit-transform: translateZ(0);
.sex-right-btned
font-weight: 500
width: 224rpx;
@@ -347,4 +384,7 @@ export default {
background: rgba(37,107,250,0.06);
border: 2rpx solid #256BFA;
color: #256BFA
+ /* 优化渲染性能 */
+ transform: translateZ(0);
+ -webkit-transform: translateZ(0);
diff --git a/components/selectJobs/selectJobs.vue b/components/selectJobs/selectJobs.vue
index bf438f2..1d1317c 100644
--- a/components/selectJobs/selectJobs.vue
+++ b/components/selectJobs/selectJobs.vue
@@ -17,6 +17,7 @@