Browse Source

优化uv-tabs滚动逻辑

shmily1213 1 ngày trước cách đây
mục cha
commit
cdd845607c

+ 15 - 11
src/composables/useExam.ts

@@ -12,7 +12,7 @@ const getNow = (): number => {
   // #ifdef MP-WEIXIN
   return Date.now();
   // #endif
-  
+
   // #ifndef MP-WEIXIN
   if (typeof performance !== 'undefined' && performance.now) {
     return performance.now();
@@ -31,7 +31,7 @@ const requestAnimFrame = (() => {
     return setTimeout(() => callback(Date.now()), 1000 / 60) as unknown as number;
   };
   // #endif
-  
+
   // #ifndef MP-WEIXIN
   if (typeof requestAnimationFrame !== 'undefined') {
     return requestAnimationFrame;
@@ -52,7 +52,7 @@ const cancelAnimFrame = (() => {
     clearTimeout(id as unknown as NodeJS.Timeout);
   };
   // #endif
-  
+
   // #ifndef MP-WEIXIN
   if (typeof cancelAnimationFrame !== 'undefined') {
     return cancelAnimationFrame;
@@ -588,7 +588,9 @@ export const useExam = () => {
     if (currentQuestion.value.activeSubIndex < currentQuestion.value.subQuestions.length - 1) {
       currentQuestion.value.activeSubIndex++;
     } else {
-      currentIndex.value++;
+      const lastIndex = currentIndex.value + 1;
+      questionList.value[lastIndex].activeSubIndex = 0;
+      currentIndex.value = lastIndex;
     }
   }
   // 上一题
@@ -600,7 +602,9 @@ export const useExam = () => {
       if (currentQuestion.value.activeSubIndex > 0) {
         currentQuestion.value.activeSubIndex--;
       } else {
-        currentIndex.value--;
+        const prevIndex = currentIndex.value - 1;
+        questionList.value[prevIndex].activeSubIndex = questionList.value[prevIndex].subQuestions.length - 1;
+        currentIndex.value = prevIndex;
       }
     } else {
       if (currentIndex.value > 0) {
@@ -652,12 +656,12 @@ export const useExam = () => {
   // 开始计时
   const startTiming = () => {
     startCount();
-    
+
     // 记录开始时间戳(毫秒)
     if (practiceStartTime === 0) {
       practiceStartTime = getNow();
     }
-    
+
     // 使用 requestAnimFrame 更新显示,更流畅且性能更好
     // 兼容微信小程序环境
     const updatePracticeDuration = () => {
@@ -669,20 +673,20 @@ export const useExam = () => {
         animationFrameId = requestAnimFrame(updatePracticeDuration);
       }
     };
-    
+
     // 开始动画帧循环
     animationFrameId = requestAnimFrame(updatePracticeDuration);
   }
   // 停止计时
   const stopTiming = () => {
     stopCount();
-    
+
     // 取消动画帧
     if (animationFrameId !== null) {
       cancelAnimFrame(animationFrameId);
       animationFrameId = null;
     }
-    
+
     // 如果正在计时,累加经过的时间
     if (practiceStartTime > 0) {
       const elapsed = (getNow() - practiceStartTime) / 1000;
@@ -806,7 +810,7 @@ export const useExam = () => {
         virtualIndex: 0,
         duration: 0,
         activeSubIndex: 0,
-        hasSubQuestions: item.subQuestions?.length > 0,
+        hasSubQuestions: item.subQuestions && item.subQuestions.length > 0,
         typeTitle: item.typeTitle
       } as Study.Question
     }

+ 0 - 1
src/main.ts

@@ -51,7 +51,6 @@ export function createApp() {
       },
       tabs: {
         activeStyle: { default: () => ({ color: 'var(--primary-color)' }) },
-        autoScroll: { default: true }, // current 改变时是否自动滚动到中间
         animationEnabled: { default: true } // 滚动时是否带有动画
       },
       steps: {

+ 5 - 16
src/pagesStudy/pages/exam-start/components/question-item.vue

@@ -7,8 +7,8 @@
       <question-parse :question="question" />
     </template>
     <view v-else class="mt-20">
-      <uv-tabs ref="tabRef" :current="question.activeSubIndex" :autoScroll="autoScroll" keyName="label"
-        :animationEnabled="false" :itemStyle="tabItemStyle" :list="tabs" :scrollable="true" lineHeight="0"
+      <uv-tabs ref="tabRef" :current="question.activeSubIndex" keyName="label"
+        :animationEnabled="true" :itemStyle="tabItemStyle" :list="tabs" :scrollable="true" lineHeight="0"
         @change="handleTabChange">
         <template #default="{ data: { item, index } }">
           <view class="px-40 py-8 rounded-full"
@@ -64,22 +64,11 @@ const tabItemStyle = {
   padding: '0 5px',
 };
 
-watch(() => props.question.activeSubIndex, (val) => {
-  if (currentIndex.value === props.question.index) {
-    autoScroll.value = true;
-  }
-}, {
-  immediate: false
-});
 watch(() => currentIndex.value, (val) => {
   if (currentIndex.value === props.question.index) {
-    setTimeout(() => {
-      nextTick(() => {
-        tabRef.value?.init();
-      });
-    }, 0);
-  } else {
-    autoScroll.value = false;
+    nextTick(() => {
+      tabRef.value?.init();
+    });
   }
 }, {
   immediate: false

+ 0 - 1
src/pagesStudy/pages/exam-start/components/question-options.vue

@@ -194,7 +194,6 @@ const handleSelect = async (option: Study.QuestionOption) => {
 const handleShowParse = () => {
   props.question.showParse = !props.question.showParse;
 }
-console.log(props.question, 111)
 </script>
 <style lang="scss" scoped>
 .question-options {

+ 1 - 1
src/pagesStudy/pages/exam-start/components/question-parse.vue

@@ -1,7 +1,7 @@
 <template>
   <view v-if="(isReadOnly) || (!isReadOnly && question.showParse)" class="mt-40">
     <!-- 主观题的答案在这里显示,其他题型在 question-result 面板显示 -->
-    <view v-if="isOnlySubjective" class="mb-20">
+    <view class="mb-20">
       <view class="text-30 text-fore-title font-bold">答案</view>
       <view class="mt-10 text-26 text-fore-light">
         <mp-html :content="decodeHtmlEntities(question.answer2 || '略')" />

+ 0 - 1
src/pagesStudy/pages/simulation-analysis/components/exam-stat.vue

@@ -131,7 +131,6 @@ const handleDetail = (item: Study.Question) => {
   emit('detail', item);
 }
 setQuestionList(props.data.questions);
-console.log(flatQuestionList.value, 111)
 </script>
 <style lang="scss" scoped>
 .question-item {

+ 4 - 3
src/uni_modules/uv-tabs/components/uv-tabs/uv-tabs.vue

@@ -138,7 +138,7 @@
 				immediate: true,
 				handler (newValue, oldValue) {
 					// 内外部值不相等时,才尝试移动滑块
-					if (this.autoScroll && newValue !== this.innerCurrent) {
+					if (newValue !== this.innerCurrent) {
 						this.innerCurrent = newValue
 						this.$nextTick(() => {
 							this.resize()
@@ -266,8 +266,9 @@
 				// 此处为屏幕宽度
 				const windowWidth = this.$uv.sys().windowWidth
 				// 将活动的tabs-item移动到屏幕正中间,实际上是对scroll-view的移动
-				let scrollLeft = offsetLeft - (this.tabsRect.width - tabRect.rect.width) / 2 - (windowWidth - this.tabsRect
-					.right) / 2 + this.tabsRect.left / 2
+				// let scrollLeft = offsetLeft - (this.tabsRect.width - tabRect.rect.width) / 2 - (windowWidth - this.tabsRect
+				// 	.right) / 2 + this.tabsRect.left / 2
+        let scrollLeft = offsetLeft + tabRect.rect.width / 2 - this.tabsRect.width / 2;
 				// 这里做一个限制,限制scrollLeft的最大值为整个scroll-view宽度减去tabs组件的宽度
 				scrollLeft = Math.min(scrollLeft, this.scrollViewWidth - this.tabsRect.width)
 				this.scrollLeft = Math.max(0, scrollLeft)