【vue2+uni-app】页面按钮显示延迟卡顿问题的排查和解决

页面按钮显示延迟卡顿问题的排查和解决

问题复现

从列表页进入详情页,详情页底部的操作按钮会有卡顿和延迟的情况,如下图所示,同时有关闭和审批操作时,会先出现关闭按钮,再出现审批按钮;有编辑操作时,先闪现关闭按钮,然后关闭按钮消失,出现编辑按钮。
虽然不影响功能,但是对用户来说交互并不友好,所以需要优化一下
在这里插入图片描述

排查思路

样式问题还是逻辑问题

<scroll-view>
	......
</scroll-view>
<view class="option-group-box" v-if="canApproval || canEdit || canClose">
	<view class="option-btn submite-btn" v-if="canApproval" @click="goToApproval">审批</view>
	<view class="option-btn submite-btn" v-if="canEdit" @click="goToEdit">编辑</view>
	<view class="option-btn submite-btn" v-if="canClose" @click="goToClose">关闭</view>
</view>

样式问题排查:
1、给按钮区足够大的固定高度,没有变化
2、按钮区的判断问题,取消对option-group-box的判断,默认展示,没有变化
3、scroll-view区域挤压导致,给scroll-view固定小的高度,没有变化
逻辑问题排查:

 	canApproval() {
		 	return ['approvalPendingList'].includes(this.pageParams.source);
		 },
	canEdit() {
	 	return ['mineSubmitList'].includes(this.pageParams.source) && ['1'].includes(this.pageData.auditStatus + '');
	 },
	 canClose() {
	 	return ['0', '2', '4'].includes(this.pageData.auditStatus + '') && this.permissions['corrective-maintenance-close'];
	 }

审批、编辑、关闭按钮都是通过在计算属性中判断返回,所以在对应计算属性中打断点,发现编辑和关闭按钮会出现多次打断情况,说明这两个操作的计算属性判断需要的字段有变化,导致重新计算属性,DOM重新更新

问题原因

检查代码发现,进入页面后会先调详情接口,获取到缺陷单号后作为参数再调用一个接口,获取最新的缺陷状态和关闭原因等字段,所以除了初始化的时候计算属性会先计算一次,调用第一个详情接口后计算属性会再判断一次,显示对应的按钮,调第二个接口后因为计算属性需要的auditStatus 字段更新了,计算属性还会再判断一次,按钮再次更新,有可能第一次展示了一个按钮,第二个接口判断后不展示了,呈现出类似卡顿和延迟的效果。

页面初始化时执行getFlowDetails,第一次调接口:

	onShow(option) {
		let pages = getCurrentPages();
		let currentPages = pages[pages.length - 1];
		this.pageParams.processInstanceId && this.getFlowDetails();
	},

getFlowDetails方法中接口第一次返回auditStatus ,计算属性更新一次,然后第二次调接口:

async getFlowDetails() {
	this.$modal.loading('加载中...', {
		mask: true
	});
	const processInsId = this.pageParams.processInstanceId || this.auditId;
	try {
		const { code, success, data } = await flowDetail({ processInsId: processInsId });
		if (code === 200 && success) {
			......
			// 基础信息
			this.pageData = {
				......
			};
			......
			serveProcInstForm.faultTicketNo && this.getDetails(serveProcInstForm.faultTicketNo);
		}
		this.$modal.closeLoading();
	} catch (e) {
		console.log(e);
		this.$modal.closeLoading();
	}
},

第二次调接口获取最新的auditStatus ,计算属性再次更新:

getDetails(qXCode) {
	getFailureRepairDetailApi({
		code: qXCode
	}).then((res) => {
		const { code, success, data } = res;
		if (code === 200 && success && data) {
			const { id, auditStatus, updateUserName, closeReason } = data;
			this.pageData = {
				...this.pageData,
				id: id,
				auditStatus: auditStatus,
				......
			};
		
		}
	});
},

解决方法

因为计算属性计算时需要的字段会随着调用两次接口不停更新,所以不能用计算属性来判断按钮的展示,在最后一次接口调用后,数据不再变化的情况下,在判断按钮,就不会出现类似按钮停顿延迟的效果了,具体操作如下:

在data添加按钮结果的响应数据,并给初始值false:

data(){
	return{
		canApproval: false,
		canEdit: false,
		canClose: false,
		......
	}
}
	

在最后一次调用接口的方法getDetails里,接口调用后执行判断操作,结果和响应数据绑定:

getDetails(qXCode) {
	getFailureRepairDetailApi({
		code: qXCode
	}).then((res) => {
		const { code, success, data } = res;
		if (code === 200 && success && data) {
			const { id, auditStatus, updateUserName, closeReason } = data;
			this.pageData = {
				...this.pageData,
				id: id,
				auditStatus: auditStatus,
				......
			};		
			this.canApproval = ['approvalPendingList'].includes(this.pageParams.source);
			this.canEdit = ['mineSubmitList'].includes(this.pageParams.source) && ['1'].includes(this.pageData.auditStatus + '');
			this.canClose = ['0', '2', '4'].includes(this.pageData.auditStatus + '') && this.permissions['corrective-maintenance-close'];			
		}
	});
},

以上,即可实现按钮一次展示不再变化。

效果展示

在这里插入图片描述

<think>好的,用户提到在使用UniApp开发时,使用scroll-view组件不管用。我需要分析可能的原因,并给出解决方案。 首先,回忆UniApp的scroll-view常见问题。用户可能没有正确设置高度,导致无法滚动。scroll-view需要明确的高度值,比如固定高度或flex布局。检查用户代码中的scroll-view是否有高度设置。 其次,用户可能在小程序平台遇到兼容性问题。例如,在微信小程序中,scroll-view必须指定高度,并且可能需要启用enhanced属性。另外,iOSAndroid的滚动行为可能有差异,需要确认平台特定设置。 然后,查看用户提供的代码示例中的scroll-view部分。用户使用了class="flex-1",这依赖于父容器的高度。父容器是view class="h-screen overflow-hidden",h-screen可能对应100vh,但需要确保父容器正确传递高度给scroll-view。在UniApp中,flex布局可能需要显式设置高度,比如使用style或者内联样式。 另外,scroll-view的事件绑定是否正确。用户的代码中@scroll绑定了handleScroll,但未使用.passive修饰符,可能在部分平台有性能问题。不过用户之前的回答提到了使用passive修饰符优化性能,需要确认是否实际应用。 还有,滚动阈值的问题。用户的脚本中限制了scrollTop的最大值,可能导致滚动被阻止,尤其是在到达阈值后无法继续滚动。需要检查handleScroll函数中的逻辑,是否错误地限制了滚动范围。 此外,平台差异也是一个因素。比如,在H5端,scroll-view的表现可能与小程序不同,需要测试多平台。用户若未在多个平台测试,可能只在某个平台上出现问题。 可能用户没有正确引入scroll-view组件,或者版本问题导致组件异常。但UniApp内置组件通常不需要额外引入,所以可能性较低。 最后,样式冲突的可能性。比如,父容器的overflow-hidden可能影响了scroll-view的滚动区域,或者层级问题导致元素覆盖了scroll-view,使其无法接收触摸事件。 综合这些因素,应该分步骤检查scroll-view的高度设置、平台兼容性代码、事件处理逻辑以及样式布局,逐步排除问题。</think>当使用`scroll-view`出现滚动失效时,通常由以下原因导致,这里提供完整排查指南解决方案: --- ### 一、核心问题诊断(按优先级排序) 1. **高度未明确设置**(90%的案例) ```html <!-- 错误示例:没有明确高度 --> <scroll-view scroll-y> <!-- 内容 --> </scroll-view> <!-- 正确方案 --> <view class="h-screen flex flex-col"> <view class="h-[400px]">...</view> <scroll-view scroll-y class="flex-1" :style="{ height: `calc(100vh - ${headerHeight}px)` }" > <!-- 内容 --> </scroll-view> </view> ``` 2. **平台兼容性问题** ```typescript // 小程序专用修复(在onReady中执行) const setScrollViewHeight = () => { const query = uni.createSelectorQuery().in(this) query.select('.header').boundingClientRect(rect => { headerHeight.value = rect.height }).exec() } ``` 3. **事件冲突** ```html <!-- 添加滚动修饰符 --> <scroll-view @scroll.passive="handleScroll" @touchmove.stop="" <!-- 阻止事件冒泡 --> > ``` --- ### 二、跨平台优化方案 #### 通用解决方案 ```html <!-- 改进后的scroll-view结构 --> <view class="flex flex-col h-screen"> <!-- 头部 --> <view class="h-[400px] relative" :style="{ height: headerHeight + 'px' }">...</view> <!-- 滚动区域 --> <scroll-view scroll-y :scroll-top="scrollTop" :enhanced="true" <!-- 启用增强模式 --> :show-scrollbar="false" :refresher-enabled="false" class="flex-1 bg-gray-100" :style="{ height: `calc(100vh - ${dynamicHeaderHeight}px)`, '-webkit-overflow-scrolling': 'touch' }" @scroll="handleScroll" > <view v-for="item in 100" :key="item" class="p-4 bg-white m-2 rounded"> 列表项 {{ item }} </view> </scroll-view> </view> ``` #### 平台特定适配 ```typescript // 在setup脚本中添加 import { onMounted } from 'vue' onMounted(() => { // 安卓平台需要额外处理 if (uni.getSystemInfoSync().platform === 'android') { const scrollView = document.querySelector('scroll-view') scrollView?.style.setProperty('overflow-scrolling', 'auto') } // 微信小程序需要计算高度 #ifdef MP-WEIXIN const systemInfo = uni.getSystemInfoSync() const windowHeight = systemInfo.windowHeight const query = uni.createSelectorQuery() query.select('.header').boundingClientRect(rect => { const scrollHeight = windowHeight - rect.height dynamicHeaderHeight.value = rect.height scrollViewHeight.value = scrollHeight }).exec() #endif }) ``` --- ### 三、常见问题排查表 | 现象 | 检查点 | 解决方案 | |---------------------|--------------------------------|----------------------------------| | 完全无法滚动 | 1. 父容器高度是否正确<br>2. scroll-y是否启用 | 设置明确高度 + 使用`flex-1` | | iOS卡顿 | 是否启用弹性滚动 | 添加`-webkit-overflow-scrolling: touch` | | 安卓白屏 | 硬件加速问题 | 添加`transform: translateZ(0)` | | 滚动时头部抖动 | 滚动事件频率过高 | 添加防抖逻辑 | | 小程序加载后不渲染 | 高度计算时机错误 | 在`onReady`生命周期计算高度 | --- ### 四、性能优化关键代码 ```typescript // 带防抖的滚动处理 let timer: number const handleScroll = (e: UniApp.ScrollViewOnScrollEvent) => { clearTimeout(timer) timer = setTimeout(() => { scrollTop.value = Math.min(e.detail.scrollTop, maxScrollTop) // 添加视觉差效果 overlayScale.value = 1 - scrollTop.value * 0.002 }, 16) // 匹配60fps } // 使用CSS变量管理动态值 const cssVar = ref({ '--header-height': '400px', '--scroll-height': 'calc(100vh - var(--header-height))' }) ``` --- ### 五、调试技巧 1. **添加临时边框辅助调试** ```css /* 全局调试样式 */ scroll-view { border: 2px solid red !important; } ``` 2. **打印关键尺寸** ```typescript const debugLayout = () => { uni.createSelectorQuery() .select('.scroll-view') .boundingClientRect(rect => { console.log('实际渲染高度:', rect.height) }).exec() } ``` 3. **平台特性检测** ```typescript const checkPlatform = () => { console.log('当前渲染环境:', uni.getSystemInfoSync().platform, 'DPI:', uni.getSystemInfoSync().pixelRatio ) } ``` 如果仍然无法解决,建议提供以下信息: 1. 出现问题的具体平台(H5/微信小程序/App2. 添加的`scroll-view`完整样式代码 3. 控制台是否有警告/错误信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值