refactor(views/checkin): 重构标签页逻辑为动态配置方式
将硬编码的标签页逻辑重构为基于配置的动态渲染方式 新增tab_configs配置数组管理标签页属性 优化图片点击事件处理逻辑使其支持动态标签页
Showing
1 changed file
with
71 additions
and
53 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-09-15 22:08:49 | 2 | * @Date: 2024-09-15 22:08:49 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-09-18 10:31:19 | 4 | + * @LastEditTime: 2025-09-18 11:31:33 |
| 5 | * @FilePath: /map-demo/src/views/checkin/info.vue | 5 | * @FilePath: /map-demo/src/views/checkin/info.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -41,28 +41,24 @@ | ... | @@ -41,28 +41,24 @@ |
| 41 | <div id="tab-wrapper" style="margin-top: 0.5rem;"> | 41 | <div id="tab-wrapper" style="margin-top: 0.5rem;"> |
| 42 | <van-config-provider :theme-vars="themeVars"> | 42 | <van-config-provider :theme-vars="themeVars"> |
| 43 | <van-tabs ref="tabsRef" v-model:active="active" @click-tab="clickTab" color="#DD7850" title-active-color="#DD7850" title-inactive-color="#DD7850" :shrink="show_shrink" sticky animated> | 43 | <van-tabs ref="tabsRef" v-model:active="active" @click-tab="clickTab" color="#DD7850" title-active-color="#DD7850" title-inactive-color="#DD7850" :shrink="show_shrink" sticky animated> |
| 44 | - <van-tab :title="page_details.introduction_text" v-if="page_details.introduction"> | 44 | + <template v-for="config in tab_configs" :key="config.key"> |
| 45 | - <div class="info-content"> | 45 | + <van-tab |
| 46 | - <div id="introduction" v-html="page_details.introduction" style="padding: 0 1rem;"></div> | 46 | + :title="page_details[config.title_key]" |
| 47 | - </div> | 47 | + v-if="page_details[config.content_key]" |
| 48 | - </van-tab> | 48 | + > |
| 49 | - <van-tab :title="page_details.story_text" v-if="page_details.story"> | 49 | + <div class="info-content"> |
| 50 | - <div class="info-content"> | 50 | + <div :id="config.id" v-html="page_details[config.content_key]" style="padding: 0 1rem;"></div> |
| 51 | - <div id="story" v-html="page_details.story" style="padding: 0 1rem;"></div> | ||
| 52 | - </div> | ||
| 53 | - </van-tab> | ||
| 54 | - <van-tab :title="page_details.experience_text" v-if="page_details.experience"> | ||
| 55 | - <div class="info-content"> | ||
| 56 | - <div id="experience" v-html="page_details.experience" style="padding: 0 1rem;"></div> | ||
| 57 | - </div> | ||
| 58 | - <div v-if="page_details.experience_audio.length" class="audio-wrapper"> | ||
| 59 | - <div @click="toggleHandleAudio(item, index)" :class="['audio-item', play_audio_index === index ? 'click' : '']" v-for="(item, index) in page_details.experience_audio" :key="index"> | ||
| 60 | - <div>{{ item.description }}</div> | ||
| 61 | - <van-icon @click.stop="stopAudio(item, index)" v-if="item.play" size="2rem" name="stop-circle-o" color="#DD7850" /> | ||
| 62 | - <van-icon v-else @click="playAudio(item, index)" size="2rem" name="https://cdn.ipadbiz.cn/bieyuan/map/icon/audio_icon.png" /> | ||
| 63 | </div> | 51 | </div> |
| 64 | - </div> | 52 | + <!-- 音频播放器只在体验标签页显示 --> |
| 65 | - </van-tab> | 53 | + <div v-if="config.key === 'experience' && page_details.experience_audio && page_details.experience_audio.length" class="audio-wrapper"> |
| 54 | + <div @click="toggleHandleAudio(item, index)" :class="['audio-item', play_audio_index === index ? 'click' : '']" v-for="(item, index) in page_details.experience_audio" :key="index"> | ||
| 55 | + <div>{{ item.description }}</div> | ||
| 56 | + <van-icon @click.stop="stopAudio(item, index)" v-if="item.play" size="2rem" name="stop-circle-o" color="#DD7850" /> | ||
| 57 | + <van-icon v-else @click="playAudio(item, index)" size="2rem" name="https://cdn.ipadbiz.cn/bieyuan/map/icon/audio_icon.png" /> | ||
| 58 | + </div> | ||
| 59 | + </div> | ||
| 60 | + </van-tab> | ||
| 61 | + </template> | ||
| 66 | </van-tabs> | 62 | </van-tabs> |
| 67 | </van-config-provider> | 63 | </van-config-provider> |
| 68 | </div> | 64 | </div> |
| ... | @@ -120,6 +116,31 @@ const props = defineProps({ | ... | @@ -120,6 +116,31 @@ const props = defineProps({ |
| 120 | 116 | ||
| 121 | const page_details = ref({}); | 117 | const page_details = ref({}); |
| 122 | 118 | ||
| 119 | +// TAG: 动态标签页配置 | ||
| 120 | +const tab_configs = ref([ | ||
| 121 | + { | ||
| 122 | + key: 'introduction', | ||
| 123 | + title_key: 'introduction_text', | ||
| 124 | + content_key: 'introduction', | ||
| 125 | + default_title: '敬老月优惠', | ||
| 126 | + id: 'introduction' | ||
| 127 | + }, | ||
| 128 | + { | ||
| 129 | + key: 'story', | ||
| 130 | + title_key: 'story_text', | ||
| 131 | + content_key: 'story', | ||
| 132 | + default_title: '故 事', | ||
| 133 | + id: 'story' | ||
| 134 | + }, | ||
| 135 | + { | ||
| 136 | + key: 'experience', | ||
| 137 | + title_key: 'experience_text', | ||
| 138 | + content_key: 'experience', | ||
| 139 | + default_title: '体 验', | ||
| 140 | + id: 'experience' | ||
| 141 | + } | ||
| 142 | +]); | ||
| 143 | + | ||
| 123 | // 监听props.info变化,更新页面数据并检查打卡状态 | 144 | // 监听props.info变化,更新页面数据并检查打卡状态 |
| 124 | watch( | 145 | watch( |
| 125 | () => props.info, | 146 | () => props.info, |
| ... | @@ -127,10 +148,10 @@ watch( | ... | @@ -127,10 +148,10 @@ watch( |
| 127 | if (newInfo && newInfo.details && newInfo.details.length) { | 148 | if (newInfo && newInfo.details && newInfo.details.length) { |
| 128 | // 更新page_details数据 | 149 | // 更新page_details数据 |
| 129 | page_details.value = { ...newInfo.details[0], position: newInfo.position, path: newInfo.path, current_lng: newInfo.current_lng, current_lat: newInfo.current_lat, openid: newInfo.openid }; | 150 | page_details.value = { ...newInfo.details[0], position: newInfo.position, path: newInfo.path, current_lng: newInfo.current_lng, current_lat: newInfo.current_lat, openid: newInfo.openid }; |
| 130 | - // TODO: 模拟假的tab文字 | 151 | + // 动态设置标签页标题(使用默认值或接口返回值) |
| 131 | - page_details.value.introduction_text = '敬老月优惠'; | 152 | + tab_configs.value.forEach(config => { |
| 132 | - page_details.value.story_text = '百联繁花里'; | 153 | + page_details.value[config.title_key] = page_details.value[config.title_key] || config.default_title; |
| 133 | - page_details.value.experience_text = '体 验'; | 154 | + }); |
| 134 | // 获取浏览器可视范围的高度 | 155 | // 获取浏览器可视范围的高度 |
| 135 | $('.info-page').height(props.height + 'px'); | 156 | $('.info-page').height(props.height + 'px'); |
| 136 | // 检查打卡状态 | 157 | // 检查打卡状态 |
| ... | @@ -220,10 +241,10 @@ onMounted(async () => { | ... | @@ -220,10 +241,10 @@ onMounted(async () => { |
| 220 | page_details.value.introduction = page_details.value.introduction?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') | 241 | page_details.value.introduction = page_details.value.introduction?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') |
| 221 | page_details.value.story = page_details.value.story?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') | 242 | page_details.value.story = page_details.value.story?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') |
| 222 | page_details.value.experience = page_details.value.experience?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') | 243 | page_details.value.experience = page_details.value.experience?.replace(/\<hr\>/g, '<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>') |
| 223 | - // TODO: 模拟假的tab文字 | 244 | + // 动态设置标签页标题(使用默认值或接口返回值) |
| 224 | - page_details.value.introduction_text = '敬老月优惠'; | 245 | + tab_configs.value.forEach(config => { |
| 225 | - page_details.value.story_text = '百联繁花里'; | 246 | + page_details.value[config.title_key] = page_details.value[config.title_key] || config.default_title; |
| 226 | - page_details.value.experience_text = '体 验'; | 247 | + }); |
| 227 | // 定位 | 248 | // 定位 |
| 228 | if (current_lng && current_lat) { | 249 | if (current_lng && current_lat) { |
| 229 | page_details.value.current_lng = current_lng; | 250 | page_details.value.current_lng = current_lng; |
| ... | @@ -395,30 +416,27 @@ const tabsRef = ref(null); | ... | @@ -395,30 +416,27 @@ const tabsRef = ref(null); |
| 395 | const clickTab = (evt) => { // 标签切换 | 416 | const clickTab = (evt) => { // 标签切换 |
| 396 | tabsRef.value.resize(); | 417 | tabsRef.value.resize(); |
| 397 | nextTick(() => { | 418 | nextTick(() => { |
| 398 | - if (evt.title === '敬老月优惠') { // 介绍 | 419 | + // 根据当前激活的标签页动态获取对应的图片 |
| 399 | - var imgs = $('#introduction').find('img'); | 420 | + const currentConfig = tab_configs.value[evt.index]; |
| 400 | - } | 421 | + if (currentConfig) { |
| 401 | - if (evt.title === '百联繁花里') { // 故事 | 422 | + const imgs = $(`#${currentConfig.id}`).find('img'); |
| 402 | - var imgs = $('#story').find('img'); | 423 | + |
| 403 | - } | 424 | + // 图片点击事件 |
| 404 | - if (evt.title === '体 验') { // 体验 | 425 | + imgs.each(function(index, img) { |
| 405 | - var imgs = $('#experience').find('img'); | 426 | + $(img).on('click', function (e) { |
| 406 | - } | 427 | + showImagePreview({ |
| 407 | - // 图片点击事件 | 428 | + images: [$(img).attr('src')], |
| 408 | - imgs.each(function(index, img) { | 429 | + startPosition: 0, |
| 409 | - $(img).on('click', function (e) { | 430 | + showIndex: false, |
| 410 | - showImagePreview({ | 431 | + onClose: () => { |
| 411 | - images: [$(img).attr('src')], | 432 | + // console.log('close'); |
| 412 | - startPosition: 0, | 433 | + } |
| 413 | - showIndex: false, | 434 | + }) |
| 414 | - onClose: () => { | 435 | + }) |
| 415 | - // console.log('close'); | 436 | + // 图片有5个像素的圆角 |
| 416 | - } | 437 | + $(img).css('border-radius', '5px'); |
| 417 | - }) | ||
| 418 | }) | 438 | }) |
| 419 | - // 图片有5个像素的圆角 | 439 | + } |
| 420 | - $(img).css('border-radius', '5px'); | ||
| 421 | - }); | ||
| 422 | // 滚动高度大于tabs高度后才滚动到指定高度 | 440 | // 滚动高度大于tabs高度后才滚动到指定高度 |
| 423 | let offsetTop = $('#tab-wrapper')[0].offsetTop; | 441 | let offsetTop = $('#tab-wrapper')[0].offsetTop; |
| 424 | if (scrollTop.value >= offsetTop) { | 442 | if (scrollTop.value >= offsetTop) { | ... | ... |
-
Please register or login to post a comment