test(图片网络加载): 网络加载图片、结合缓存、懒加载、预加载功能试点
This commit is contained in:
parent
ca5ffdc042
commit
846debb8da
@ -1,7 +1,26 @@
|
|||||||
|
<!-- src/components/itemCenter.vue -->
|
||||||
<template>
|
<template>
|
||||||
<div style="position: relative; width: 100%">
|
<div style="position: relative; width: 100%" ref="containerRef">
|
||||||
<!-- 背景图 -->
|
<!-- 背景图 -->
|
||||||
<img v-smart-img :src="imgUrl" :key="imgUrl" alt="" width="100%" style="display: block" />
|
<img
|
||||||
|
v-if="shouldShowImage"
|
||||||
|
v-smart-img
|
||||||
|
:src="imgUrl"
|
||||||
|
:key="imgUrl"
|
||||||
|
alt=""
|
||||||
|
width="100%"
|
||||||
|
style="display: block"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="placeholder"
|
||||||
|
:style="{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
backgroundColor: '#f0f0f0',
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
|
|
||||||
<!-- 内容 -->
|
<!-- 内容 -->
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
@ -19,18 +38,76 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref, onMounted, computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
imgUrl: {
|
imgUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// 内容样式
|
|
||||||
contentStyle: {
|
contentStyle: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 是否启用懒加载
|
||||||
|
lazy: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 是否立即显示(优先级高于lazy)
|
||||||
|
immediate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const containerRef = ref(null)
|
||||||
|
const isVisible = ref(false)
|
||||||
|
|
||||||
|
// 是否应该显示图片
|
||||||
|
const shouldShowImage = computed(() => {
|
||||||
|
// 如果标记为立即显示或禁用懒加载,则直接显示
|
||||||
|
if (props.immediate || !props.lazy) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则根据是否可见决定
|
||||||
|
return isVisible.value
|
||||||
|
})
|
||||||
|
|
||||||
|
// 创建交叉观察器
|
||||||
|
const createObserver = () => {
|
||||||
|
if (!props.lazy || props.immediate) return
|
||||||
|
|
||||||
|
if (!containerRef.value) return
|
||||||
|
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
isVisible.value = true
|
||||||
|
observer.unobserve(entry.target)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rootMargin: '100px', // 提前100px开始加载
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
observer.observe(containerRef.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
createObserver()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.placeholder {
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
8
src/config/imagePaths.js
Normal file
8
src/config/imagePaths.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// src/config/imagePaths.js
|
||||||
|
export const OSS_BASE_URL = 'https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5/' // 阿里云oss
|
||||||
|
// export const OMAN_NATIONAL_DAY_PATH = 'Activities/Oman/NationalDay/'// 文件路径
|
||||||
|
|
||||||
|
// 组合使用示例
|
||||||
|
export const getPngUrl = (imagePath, filename) => {
|
||||||
|
return `${OSS_BASE_URL}${imagePath}${filename}.png`
|
||||||
|
}
|
||||||
@ -13,6 +13,7 @@ class ImageCacheManager {
|
|||||||
await this.checkVersionAndUpdate()
|
await this.checkVersionAndUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 版本检查逻辑
|
||||||
async checkVersionAndUpdate() {
|
async checkVersionAndUpdate() {
|
||||||
const cachedVersion = localStorage.getItem(this.cacheVersionKey)
|
const cachedVersion = localStorage.getItem(this.cacheVersionKey)
|
||||||
|
|
||||||
@ -91,6 +92,12 @@ class ImageCacheManager {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增:允许缓存特定域名下的资源
|
||||||
|
const ossBaseUrl = 'https://tkm-likei.oss-ap-southeast-1.aliyuncs.com/h5'
|
||||||
|
if (url.startsWith(ossBaseUrl)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('判断资源类型时出错:', error)
|
console.warn('判断资源类型时出错:', error)
|
||||||
@ -172,16 +179,26 @@ class ImageCacheManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadImageFromNetwork(src, resolve, reject) {
|
async loadImageFromNetwork(src, resolve, reject) {
|
||||||
const img = new Image()
|
try {
|
||||||
img.onload = async () => {
|
const response = await fetch(src)
|
||||||
resolve(img)
|
if (response.ok) {
|
||||||
// 只有本地资源才缓存
|
const img = new Image()
|
||||||
if (this.isBuildAsset(src)) {
|
img.onload = async () => {
|
||||||
await this.cacheImage(src)
|
resolve(img)
|
||||||
|
// 缓存带有 ETag 的响应
|
||||||
|
if (this.isBuildAsset(src)) {
|
||||||
|
const cache = await caches.open(this.cacheName)
|
||||||
|
await cache.put(src, response.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img.onerror = reject
|
||||||
|
img.src = URL.createObjectURL(await response.blob())
|
||||||
|
} else {
|
||||||
|
reject(new Error(`HTTP ${response.status}`))
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
reject(error)
|
||||||
}
|
}
|
||||||
img.onerror = reject
|
|
||||||
img.src = src
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,55 +1,33 @@
|
|||||||
// src/utils/imagePreloader.js
|
// src/utils/imagePreloader.js
|
||||||
|
import { imageCacheManager } from '@/utils/imageCacheManager'
|
||||||
|
|
||||||
/**
|
export const preloadImages = (sources, options = {}) => {
|
||||||
* 简单图片预加载函数
|
const { useSmartCache = false } = options
|
||||||
* @param {Array|string|Object} sources - 图片源(数组、字符串或对象)
|
|
||||||
*/
|
|
||||||
export const preloadImages = (sources) => {
|
|
||||||
let urls = []
|
let urls = []
|
||||||
|
|
||||||
if (Array.isArray(sources)) {
|
if (Array.isArray(sources)) {
|
||||||
urls = sources
|
urls = sources
|
||||||
} else if (typeof sources === 'string') {
|
|
||||||
urls = [sources]
|
|
||||||
} else if (typeof sources === 'object') {
|
} else if (typeof sources === 'object') {
|
||||||
urls = Object.values(sources)
|
urls = Object.values(sources)
|
||||||
}
|
}
|
||||||
|
|
||||||
urls.forEach((url) => {
|
if (useSmartCache) {
|
||||||
const img = new Image()
|
// 使用 SmartImage 缓存系统
|
||||||
img.src = url
|
urls.forEach((url) => {
|
||||||
})
|
if (imageCacheManager.isBuildAsset(url)) {
|
||||||
|
imageCacheManager.loadImage(url) // 触发缓存
|
||||||
|
} else {
|
||||||
|
const img = new Image()
|
||||||
|
img.src = url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 使用浏览器默认缓存
|
||||||
|
urls.forEach((url) => {
|
||||||
|
const img = new Image()
|
||||||
|
img.src = url
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
console.log(`开始预加载 ${urls.length} 张图片`)
|
console.log(`开始预加载 ${urls.length} 张图片`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 带进度监控的图片预加载函数
|
|
||||||
* @param {Array|string|Object} sources - 图片源
|
|
||||||
* @param {Function} onProgress - 进度回调
|
|
||||||
*/
|
|
||||||
export const preloadImagesWithProgress = (sources, onProgress) => {
|
|
||||||
let urls = []
|
|
||||||
|
|
||||||
if (Array.isArray(sources)) {
|
|
||||||
urls = sources
|
|
||||||
} else if (typeof sources === 'string') {
|
|
||||||
urls = [sources]
|
|
||||||
} else if (typeof sources === 'object') {
|
|
||||||
urls = Object.values(sources)
|
|
||||||
}
|
|
||||||
|
|
||||||
let loaded = 0
|
|
||||||
const total = urls.length
|
|
||||||
|
|
||||||
urls.forEach((url) => {
|
|
||||||
const img = new Image()
|
|
||||||
img.onload = img.onerror = () => {
|
|
||||||
loaded++
|
|
||||||
if (onProgress) {
|
|
||||||
onProgress({ loaded, total, url })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
img.src = url
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<!-- src/views/Activities/heroesDay/index.vue -->
|
<!-- src/views/Activities/Oman/NationalDay/index.vue -->
|
||||||
<template>
|
<template>
|
||||||
<div class="fullPage">
|
<div class="fullPage">
|
||||||
<!-- 新增的背景图层 -->
|
<!-- 新增的背景图层 -->
|
||||||
<div class="background-overlay"></div>
|
<div class="background-overlay"></div>
|
||||||
|
|
||||||
<div class="bg">
|
<div class="bg" :style="{ '--bg-url': `url(${imageUrl('bg')})` }">
|
||||||
<!-- 状态栏占位区域(仅在APP中显示) -->
|
<!-- 状态栏占位区域(仅在APP中显示) -->
|
||||||
<div v-if="isInAppEnvironment" style="height: 30px"></div>
|
<div v-if="isInAppEnvironment" style="height: 30px"></div>
|
||||||
|
|
||||||
@ -23,25 +23,25 @@
|
|||||||
<!-- 倒计时 -->
|
<!-- 倒计时 -->
|
||||||
<div style="display: flex; justify-content: center; gap: 4px; margin-top: 1vw">
|
<div style="display: flex; justify-content: center; gap: 4px; margin-top: 1vw">
|
||||||
<div style="width: 20%">
|
<div style="width: 20%">
|
||||||
<itemCenter :imgUrl="images.timeDayBg">
|
<itemCenter :imgUrl="imageUrl('timeDayBg')">
|
||||||
<div class="timeText" style="margin-bottom: 20%">{{ Days }}D</div>
|
<div class="timeText" style="margin-bottom: 20%">{{ Days }}D</div>
|
||||||
</itemCenter>
|
</itemCenter>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeText timeGap" style="width: 6px"></div>
|
<div class="timeText timeGap" style="width: 6px"></div>
|
||||||
<div style="width: 20%">
|
<div style="width: 20%">
|
||||||
<itemCenter :imgUrl="images.timeHourBg">
|
<itemCenter :imgUrl="imageUrl('timeHourBg')">
|
||||||
<div class="timeText" style="margin-bottom: 20%">{{ Hours }}</div>
|
<div class="timeText" style="margin-bottom: 20%">{{ Hours }}</div>
|
||||||
</itemCenter>
|
</itemCenter>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeText timeGap">:</div>
|
<div class="timeText timeGap">:</div>
|
||||||
<div style="width: 20%">
|
<div style="width: 20%">
|
||||||
<itemCenter :imgUrl="images.timeMinBg">
|
<itemCenter :imgUrl="imageUrl('timeMinBg')">
|
||||||
<div class="timeText" style="margin-bottom: 20%">{{ Minutes }}</div>
|
<div class="timeText" style="margin-bottom: 20%">{{ Minutes }}</div>
|
||||||
</itemCenter>
|
</itemCenter>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeText timeGap">:</div>
|
<div class="timeText timeGap">:</div>
|
||||||
<div style="width: 20%">
|
<div style="width: 20%">
|
||||||
<itemCenter :imgUrl="images.timeSecBg">
|
<itemCenter :imgUrl="imageUrl('timeSecBg')">
|
||||||
<div class="timeText" style="margin-bottom: 20%">{{ Second }}</div>
|
<div class="timeText" style="margin-bottom: 20%">{{ Second }}</div>
|
||||||
</itemCenter>
|
</itemCenter>
|
||||||
</div>
|
</div>
|
||||||
@ -49,21 +49,22 @@
|
|||||||
|
|
||||||
<!-- 每周礼物 -->
|
<!-- 每周礼物 -->
|
||||||
<div style="display: flex; justify-content: center; margin-top: 10px">
|
<div style="display: flex; justify-content: center; margin-top: 10px">
|
||||||
<itemCenter :imgUrl="images.giftsBg" :contentStyle="'paddingTop: 10%;'">
|
<itemCenter :imgUrl="imageUrl('giftsBg')" :contentStyle="'paddingTop: 10%;'">
|
||||||
<div style="width: 85%; display: flex; justify-content: space-around; margin-top: 10%">
|
<div style="width: 85%; display: flex; justify-content: space-around; margin-top: 10%">
|
||||||
<div
|
<div
|
||||||
v-for="(gift, index) in gifts"
|
v-for="(gift, index) in gifts"
|
||||||
:key="index"
|
:key="index"
|
||||||
style="width: 30%; display: flex; flex-direction: column"
|
style="width: 30%; display: flex; flex-direction: column"
|
||||||
>
|
>
|
||||||
<itemCenter :imgUrl="images.giftItemBg"
|
<itemCenter :imgUrl="imageUrl('giftItemBg')">
|
||||||
><img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="gift.giftPhoto"
|
:src="gift.giftPhoto"
|
||||||
alt=""
|
alt=""
|
||||||
width="70%"
|
width="70%"
|
||||||
style="display: block; object-fit: cover"
|
style="display: block; object-fit: cover"
|
||||||
/></itemCenter>
|
/>
|
||||||
|
</itemCenter>
|
||||||
<div style="display: flex; justify-content: center; align-items: center; gap: 5px">
|
<div style="display: flex; justify-content: center; align-items: center; gap: 5px">
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
@ -84,14 +85,14 @@
|
|||||||
<div style="display: flex; justify-content: space-around">
|
<div style="display: flex; justify-content: space-around">
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="rankingShow ? images.rankingBtActive : images.rankingBt"
|
:src="rankingShow ? imageUrl('rankingBtActive') : imageUrl('rankingBt')"
|
||||||
alt=""
|
alt=""
|
||||||
style="display: block; width: 40%"
|
style="display: block; width: 40%"
|
||||||
@click="rankingShow = true"
|
@click="rankingShow = true"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="!rankingShow ? images.rewardBtActive : images.rewardsBt"
|
:src="!rankingShow ? imageUrl('rewardBtActive') : imageUrl('rewardsBt')"
|
||||||
alt=""
|
alt=""
|
||||||
style="display: block; width: 40%"
|
style="display: block; width: 40%"
|
||||||
@click="rankingShow = false"
|
@click="rankingShow = false"
|
||||||
@ -113,12 +114,12 @@
|
|||||||
></div>
|
></div>
|
||||||
<div style="position: relative; z-index: 1">
|
<div style="position: relative; z-index: 1">
|
||||||
<!-- 前三名 -->
|
<!-- 前三名 -->
|
||||||
<itemCenter :imgUrl="images.RankingMain" :contentStyle="`padding: 25% 7% 10%`">
|
<itemCenter :imgUrl="imageUrl('RankingMain')" :contentStyle="`padding: 25% 7% 10%`">
|
||||||
<div style="margin-top: 13%">
|
<div style="margin-top: 13%">
|
||||||
<!-- 第一 -->
|
<!-- 第一 -->
|
||||||
<div style="display: flex; justify-content: center">
|
<div style="display: flex; justify-content: center">
|
||||||
<TopUser
|
<TopUser
|
||||||
:BorderImgUrl="images.topOne"
|
:BorderImgUrl="imageUrl('topOne')"
|
||||||
:avatarUrl="RankingHasTop3[0].avatar"
|
:avatarUrl="RankingHasTop3[0].avatar"
|
||||||
:name="RankingHasTop3[0].nickname"
|
:name="RankingHasTop3[0].nickname"
|
||||||
:distributionValue="RankingHasTop3[0].quantity"
|
:distributionValue="RankingHasTop3[0].quantity"
|
||||||
@ -131,7 +132,7 @@
|
|||||||
<TopUser
|
<TopUser
|
||||||
:isTopOne="false"
|
:isTopOne="false"
|
||||||
ranking="2"
|
ranking="2"
|
||||||
:BorderImgUrl="images.topTwo"
|
:BorderImgUrl="imageUrl('topTwo')"
|
||||||
:avatarUrl="RankingHasTop3[1].avatar"
|
:avatarUrl="RankingHasTop3[1].avatar"
|
||||||
:name="RankingHasTop3[1].nickname"
|
:name="RankingHasTop3[1].nickname"
|
||||||
:distributionValue="RankingHasTop3[1].quantity"
|
:distributionValue="RankingHasTop3[1].quantity"
|
||||||
@ -141,7 +142,7 @@
|
|||||||
<TopUser
|
<TopUser
|
||||||
:isTopOne="false"
|
:isTopOne="false"
|
||||||
ranking="3"
|
ranking="3"
|
||||||
:BorderImgUrl="images.topThree"
|
:BorderImgUrl="imageUrl('topThree')"
|
||||||
:avatarUrl="RankingHasTop3[2].avatar"
|
:avatarUrl="RankingHasTop3[2].avatar"
|
||||||
:name="RankingHasTop3[2].nickname"
|
:name="RankingHasTop3[2].nickname"
|
||||||
:distributionValue="RankingHasTop3[2].quantity"
|
:distributionValue="RankingHasTop3[2].quantity"
|
||||||
@ -156,8 +157,11 @@
|
|||||||
<div v-if="showRanking.length > 0" style="margin-bottom: 6vw; margin-top: -10vw">
|
<div v-if="showRanking.length > 0" style="margin-bottom: 6vw; margin-top: -10vw">
|
||||||
<itemCenter
|
<itemCenter
|
||||||
v-for="listItem in showRanking"
|
v-for="listItem in showRanking"
|
||||||
:imgUrl="images.RankingItem"
|
:key="listItem.userId"
|
||||||
|
:imgUrl="imageUrl('RankingItem')"
|
||||||
:contentStyle="`padding: 0 10%`"
|
:contentStyle="`padding: 0 10%`"
|
||||||
|
:lazy="true"
|
||||||
|
:immediate="index < 2"
|
||||||
@click="viewUserInfo(listItem.userId)"
|
@click="viewUserInfo(listItem.userId)"
|
||||||
>
|
>
|
||||||
<div style="width: 75%; min-width: 0; display: flex; align-items: center">
|
<div style="width: 75%; min-width: 0; display: flex; align-items: center">
|
||||||
@ -223,7 +227,7 @@
|
|||||||
<!-- 底框 -->
|
<!-- 底框 -->
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="images.RankingBottomBorder"
|
:src="imageUrl('RankingBottomBorder')"
|
||||||
alt=""
|
alt=""
|
||||||
width="100%"
|
width="100%"
|
||||||
style="display: block; margin-top: -22vw; position: relative; z-index: 9"
|
style="display: block; margin-top: -22vw; position: relative; z-index: 9"
|
||||||
@ -250,7 +254,7 @@
|
|||||||
:key="rewardIndex"
|
:key="rewardIndex"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<itemCenter :imgUrl="images.giftItemBg">
|
<itemCenter :imgUrl="imageUrl('giftItemBg')">
|
||||||
<img
|
<img
|
||||||
v-smart-img
|
v-smart-img
|
||||||
:src="reward.cover || ''"
|
:src="reward.cover || ''"
|
||||||
@ -284,7 +288,7 @@
|
|||||||
background: linear-gradient(0deg, #6e1116 0%, #6e1116 100%), #d9d9d9;
|
background: linear-gradient(0deg, #6e1116 0%, #6e1116 100%), #d9d9d9;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
"
|
"
|
||||||
:imgUrl="images.myRankingBg"
|
:imgUrl="imageUrl('myRankingBg')"
|
||||||
:contentStyle="`padding: 2% 5% 0`"
|
:contentStyle="`padding: 2% 5% 0`"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -360,7 +364,7 @@
|
|||||||
<maskLayer :maskLayerShow="maskLayerShow" @click="maskLayerShow = false">
|
<maskLayer :maskLayerShow="maskLayerShow" @click="maskLayerShow = false">
|
||||||
<!-- help弹窗 -->
|
<!-- help弹窗 -->
|
||||||
<div style="margin: 20% 0" @click.stop>
|
<div style="margin: 20% 0" @click.stop>
|
||||||
<img v-smart-img :src="images.helpInfo" alt="" style="display: block; width: 100%" />
|
<img v-smart-img :src="imageUrl('helpInfo')" alt="" style="display: block; width: 100%" />
|
||||||
</div>
|
</div>
|
||||||
</maskLayer>
|
</maskLayer>
|
||||||
</div>
|
</div>
|
||||||
@ -368,28 +372,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { isInApp, viewUserInfo } from '@/utils/appBridge.js'
|
|
||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
|
import { isInApp, viewUserInfo } from '@/utils/appBridge.js'
|
||||||
|
import { connectToApp } from '@/utils/appConnector.js'
|
||||||
|
import { getPngUrl } from '@/config/imagePaths.js'
|
||||||
|
import { preloadImages } from '@/utils/imagePreloader.js'
|
||||||
|
|
||||||
|
import { getThisWeekRewardsAndGifts, getRankingListAndMyRanking } from '@/api/activity.js'
|
||||||
|
|
||||||
import itemCenter from '@/components/itemCenter.vue'
|
import itemCenter from '@/components/itemCenter.vue'
|
||||||
import TopUser from './components/topUser.vue'
|
import TopUser from './components/topUser.vue'
|
||||||
import maskLayer from '@/components/MaskLayer.vue'
|
import maskLayer from '@/components/MaskLayer.vue'
|
||||||
import { getThisWeekRewardsAndGifts, getRankingListAndMyRanking } from '@/api/activity.js'
|
|
||||||
import { connectToApp } from '@/utils/appConnector.js'
|
|
||||||
|
|
||||||
// vite动态批量导入图片
|
// 获取OSS图片URL的函数
|
||||||
const imageModules = import.meta.glob(
|
const imageUrl = (filename) => getPngUrl('Activities/Oman/NationalDay/', filename)
|
||||||
'@/assets/images/Activities/Oman/NationalDay/*.{png,jpg,svg}',
|
|
||||||
{
|
|
||||||
eager: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
// 生成文件名映射对象(自动移除路径和扩展名)
|
|
||||||
const images = Object.fromEntries(
|
|
||||||
Object.entries(imageModules).map(([path, module]) => {
|
|
||||||
const fileName = path.split('/').pop().split('.')[0]
|
|
||||||
return [fileName, module.default]
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
const isInAppEnvironment = ref(false) // 检测是否在APP环境中
|
const isInAppEnvironment = ref(false) // 检测是否在APP环境中
|
||||||
const maskLayerShow = ref(false) //帮助模块
|
const maskLayerShow = ref(false) //帮助模块
|
||||||
@ -409,7 +405,7 @@ const myRanking = ref({}) // 我的排名
|
|||||||
const rewardsList = ref([]) // 奖励列表
|
const rewardsList = ref([]) // 奖励列表
|
||||||
const gifts = ref([]) // 本周礼物
|
const gifts = ref([]) // 本周礼物
|
||||||
|
|
||||||
const topImg = ref([images.top1RewardBg, images.top2RewardBg, images.top3RewardBg]) // top图片
|
const topImg = ref([imageUrl('top1RewardBg'), imageUrl('top2RewardBg'), imageUrl('top3RewardBg')]) // top图片
|
||||||
|
|
||||||
// 处理排行榜小于3人时的情况
|
// 处理排行榜小于3人时的情况
|
||||||
const RankingHasTop3 = computed(() => {
|
const RankingHasTop3 = computed(() => {
|
||||||
@ -428,7 +424,6 @@ const RankingHasTop3 = computed(() => {
|
|||||||
// 展示用的榜单
|
// 展示用的榜单
|
||||||
const showRanking = computed(() => {
|
const showRanking = computed(() => {
|
||||||
return Ranking.value.filter((_, index) => index >= 3)
|
return Ranking.value.filter((_, index) => index >= 3)
|
||||||
// return []
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 奖励图片资源出错处理
|
// 奖励图片资源出错处理
|
||||||
@ -522,11 +517,42 @@ const initData = () => {
|
|||||||
getRewardsAndGifts() //获取本周的礼物和奖励列表
|
getRewardsAndGifts() //获取本周的礼物和奖励列表
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预加载关键图片
|
||||||
|
const preloadCriticalImages = () => {
|
||||||
|
const criticalImages = [
|
||||||
|
imageUrl('bg'),
|
||||||
|
imageUrl('timeDayBg'),
|
||||||
|
imageUrl('timeHourBg'),
|
||||||
|
imageUrl('timeMinBg'),
|
||||||
|
imageUrl('timeSecBg'),
|
||||||
|
imageUrl('giftsBg'),
|
||||||
|
imageUrl('giftItemBg'),
|
||||||
|
imageUrl('rankingBt'),
|
||||||
|
imageUrl('rankingBtActive'),
|
||||||
|
imageUrl('rewardBtActive'),
|
||||||
|
imageUrl('rewardsBt'),
|
||||||
|
imageUrl('RankingMain'),
|
||||||
|
imageUrl('topOne'),
|
||||||
|
imageUrl('topTwo'),
|
||||||
|
imageUrl('topThree'),
|
||||||
|
imageUrl('RankingItem'),
|
||||||
|
imageUrl('RankingBottomBorder'),
|
||||||
|
imageUrl('myRankingBg'),
|
||||||
|
imageUrl('helpInfo'),
|
||||||
|
imageUrl('top1RewardBg'),
|
||||||
|
imageUrl('top2RewardBg'),
|
||||||
|
imageUrl('top3RewardBg'),
|
||||||
|
]
|
||||||
|
|
||||||
|
preloadImages(criticalImages, { useSmartCache: true })
|
||||||
|
}
|
||||||
|
|
||||||
// 使用工具函数连接APP
|
// 使用工具函数连接APP
|
||||||
const connectToAppHandler = async () => {
|
const connectToAppHandler = async () => {
|
||||||
await connectToApp(() => {
|
await connectToApp(() => {
|
||||||
// 连接成功回调
|
// 连接成功回调
|
||||||
initData() //初始化数据
|
initData() //初始化数据
|
||||||
|
preloadCriticalImages() //预加载关键图片
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,7 +594,7 @@ onUnmounted(() => {
|
|||||||
.bg {
|
.bg {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-image: url(../../../../assets/images/Activities/Oman/NationalDay/bg.png);
|
background-image: var(--bg-url);
|
||||||
background-size: 100% auto;
|
background-size: 100% auto;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user