| | |
| | | <!-- <ioe-swiper /> --> |
| | | <!-- <div class="py-10"> --> |
| | | |
| | | |
| | | |
| | | <!-- <van-notice-bar class="font-26 textColor" left-icon="" :scrollable="false" background="transparent"> |
| | | <div slot="left-icon" class=" flex items-center more-img"><img class="w-20 h-20 more-img" |
| | | src="../../assets/Horn.png" alt=""> |
| | |
| | | class="w-20 h-20 more-img" src="../../assets/more.png" alt=""> |
| | | </div> |
| | | </van-notice-bar> --> |
| | | <!-- </div> --> |
| | | <!-- </div> --> |
| | | <!-- <cry-nav /> --> |
| | | <!-- <div class="quickly"> |
| | | <div class="quickBox chongbi" :class="THEME == 'dark' ? 'dark' : 'white'" |
| | |
| | | </div> |
| | | </div> --> |
| | | <!-- <ex-hot :listData="hList"></ex-hot> --> |
| | | <list-quatation :listData="qList" @onfetchQList="fetchQList"/> |
| | | <list-quatation :listData="qList" :hList="filteredHList" @onfetchQList="fetchQList" /> |
| | | <van-popup v-model:show="item.showPopUp" style="border-radius:10px;" :close-on-click-overlay="false" |
| | | v-for="item in popupNewsList" :key="item.id"> |
| | | <div class="w-350 p-20 box-border"> |
| | | <div class="font-700 text-center font-28 textColor">{{ item.title }}</div> |
| | | <div class="flex justify-center mt-30" v-if="item.imgUrl"><img |
| | | :src="`${item.imgUrl}`" class="w-200 h-200" alt="" /></div> |
| | | <div class="flex justify-center mt-30" v-if="item.imgUrl"><img :src="`${item.imgUrl}`" class="w-200 h-200" |
| | | alt="" /></div> |
| | | <div class="py-10 textColor content-title" v-html="item.content"></div> |
| | | <van-button color="#1194F7" class="w-full h-40 rounded-full" type="info" @click="closePopNotice(item)"> |
| | | {{ $t('我知道了') }} |
| | |
| | | import IoeSwiper from "@/components/Transform/ioe-swiper/index.vue"; |
| | | import ListQuatation from "@/components/Transform/list-quotation/index.vue"; |
| | | import { mapGetters, mapActions } from "vuex"; |
| | | import { TIME_OUT } from "@/config"; |
| | | import { TIME_OUT, QUOTE_POLLING_INTERVAL, CACHE_EXPIRE } from "@/config"; |
| | | import { SET_COIN_LIST } from '@/store/const.store' |
| | | import { _getHomeList } from '@/service/cryptos.api' |
| | | import ExHeader from "@/components/Transform/ex-header/index.vue"; |
| | |
| | | import { _getUnreadMsg } from '@/service/im.api' |
| | | import { _getNewsList1, _getPopupNews } from '@/service/user.api' |
| | | import { BASE_URL } from "@/config"; |
| | | import { _getCoinList } from '@/service/quotes.api'; |
| | | import { _getCoinList } from '@/service/quotes.api'; |
| | | const THEME = 'dark' |
| | | export default { |
| | | name: "HomePage", |
| | |
| | | [Swipe.name]: Swipe, |
| | | [SwipeItem.name]: SwipeItem, |
| | | }, |
| | | watch: { |
| | | hotArr(newVal) { |
| | | // 当热门币种列表更新时重新计算hList |
| | | if (this.qList && newVal.length) { |
| | | this.hList = this.qList.filter(item => newVal.includes(item.symbol)).slice(0, 3); |
| | | } |
| | | } |
| | | }, |
| | | async created() { |
| | | this.init(); |
| | | this.checkingMesk(); |
| | |
| | | await this.fetchQList() |
| | | }, |
| | | computed: { |
| | | // 优化:使用计算属性高效生成热门列表 |
| | | filteredHList() { |
| | | const result = []; |
| | | for (const item of this.qList) { |
| | | if (this.hotArr.includes(item.symbol)) { |
| | | result.push(item); |
| | | if (result.length >= 3) break; |
| | | } |
| | | } |
| | | return result; |
| | | }, |
| | | ...mapGetters({ |
| | | coinList: 'home/coinList', |
| | | currency: 'home/currency', |
| | |
| | | }), |
| | | }, |
| | | data() { |
| | | const arr = [] // 初始化数据 |
| | | for (let i = 0; i < 10; i++) { |
| | | arr.push({ id: i }) |
| | | } |
| | | // 优先从localStorage加载缓存数据 |
| | | const cachedData = getStorage('qoutes'); |
| | | const now = Date.now(); |
| | | const isCacheValid = cachedData && cachedData.timestamp && (now - cachedData.timestamp < CACHE_EXPIRE); |
| | | |
| | | return { |
| | | BASE_URL, |
| | | THEME, |
| | | account: "", |
| | | hList: arr.slice(0, 3), // 热门 |
| | | qList: arr, // 行情列表 |
| | | |
| | | qList: isCacheValid ? cachedData.data : [], // 行情列表 - 优先使用缓存 |
| | | active: 0, |
| | | timeout: null, |
| | | loading: true, |
| | | loading: !isCacheValid, // 有缓存数据时不显示加载状态 |
| | | announceTitle: '', |
| | | announceId: '', |
| | | announceList: [], |
| | |
| | | }) |
| | | }, |
| | | async fetchQList(v) { // 获取行情 |
| | | let coninArr = '' |
| | | // if (v) { this.getVal = v } |
| | | let arr = getStorage('qoutes') |
| | | // 优化:使用缓存数据快速展示,同时后台更新 |
| | | const cachedQuotes = getStorage('quotes'); |
| | | if (cachedQuotes && cachedQuotes.data && Date.now() - cachedQuotes.timestamp < CACHE_EXPIRE) { |
| | | this.qList = cachedQuotes.data; |
| | | this.hList = cachedQuotes.data.filter(item => this.hotArr.includes(item.symbol)).slice(0, 3); |
| | | this.loading = false; |
| | | return; |
| | | } |
| | | |
| | | // 优先用本地缓存的 coins |
| | | let coins = (arr && arr.coins && arr.coins.length) ? arr.coins : arr |
| | | // 优化:变量名修正与符号拼接 |
| | | let coinArr = ''; |
| | | const arr = getStorage('quotes'); |
| | | const coins = (arr && arr.coins && arr.coins.length) ? arr.coins : arr; |
| | | |
| | | if (coins && coins.length) { |
| | | // 如果本地有 coins,优先用本地 |
| | | coins.forEach(item => { |
| | | coninArr += item.symbol + ',' |
| | | }) |
| | | // 优化:使用map和join提升性能 |
| | | coinArr = coins.map(item => item.symbol).join(','); |
| | | } else { |
| | | // 如果本地没有 coins,拉取接口 |
| | | const quotesData = await _getCoinList() |
| | | if (quotesData && quotesData.coins && quotesData.coins.length) { |
| | | quotesData.coins.forEach(item => { |
| | | coninArr += item.symbol + ',' |
| | | }) |
| | | const quotesData = await _getCoinList().catch(err => { |
| | | console.error('获取币种列表失败:', err); |
| | | this.loading = false; // 错误状态处理 |
| | | return null; |
| | | }); |
| | | if (quotesData?.coins?.length) { |
| | | coinArr = quotesData.coins.map(item => item.symbol).join(','); |
| | | } |
| | | } |
| | | console.log('fetchQList', v, coninArr) |
| | | // if() |
| | | const list = await _getHomeList(coninArr).catch(() => { |
| | | //请求失败时,1秒后重试 |
| | | this.timeout = setTimeout(() => { |
| | | this.fetchQList() |
| | | }, 1000) |
| | | }) |
| | | if (!(list instanceof Array)) { |
| | | return |
| | | } |
| | | // console.log('接口:_getHomeList 热门:',list) |
| | | this.loading = false |
| | | // this.qList = list.slice(0,10); |
| | | this.qList = list; |
| | | const list = await _getHomeList(coinArr).catch(err => { |
| | | console.error('获取行情列表失败:', err); |
| | | this.loading = false; |
| | | return []; |
| | | }); |
| | | //请求失败时,1秒后重试 |
| | | this.timeout = setTimeout(() => { |
| | | this.fetchQList(); |
| | | }, 1000); |
| | | |
| | | this.hList = list.filter(item => this.hotArr.includes(item.symbol)); |
| | | if (this.hList.length == 4) { |
| | | this.hList.pop() |
| | | // console.log('接口:_getHomeList 热门:',list) |
| | | this.loading = false; |
| | | |
| | | // 优化:仅在获取有效数据时更新 |
| | | if (list.length) { |
| | | // 冻结数据减少响应式开销提升性能 |
| | | this.qList = Object.freeze(list); |
| | | setStorage('quotes', { data: list, timestamp: Date.now() }); |
| | | } |
| | | console.log(this.hList) |
| | | |
| | | if (this.timeout) { |
| | | clearTimeout(this.timeout) |
| | | } |
| | | // 检查缓存是否有效 |
| | | const cacheData = getStorage('quotes'); |
| | | const now = Date.now(); |
| | | const isCacheValid = cacheData && cacheData.timestamp && (now - cacheData.timestamp < CACHE_EXPIRE); |
| | | |
| | | this.timeout = setTimeout(async () => { |
| | | await this.fetchQList() |
| | | }, TIME_OUT) |
| | | // 如果缓存有效则直接使用缓存数据 |
| | | // if (isCacheValid) { |
| | | // this.qList = cacheData.data; |
| | | // this.hList = cacheData.data.filter(item => this.hotArr.includes(item.symbol)); |
| | | // if (this.hList.length === 4) this.hList.pop(); |
| | | // } else { |
| | | await this.fetchQList(); |
| | | // } |
| | | }, QUOTE_POLLING_INTERVAL); |
| | | }, |
| | | getNews() { |
| | | _getNewsList1({ |
| | | language: this.$i18n.locale, |
| | | }).then(res => { |
| | | this.announceList = res |
| | | }) |
| | | this.announceList = res; |
| | | }); |
| | | }, |
| | | getPopupNews() { |
| | | _getPopupNews({ |
| | |
| | | if (!getStorage('popNotice')) { |
| | | let list = res |
| | | list.forEach(item => { |
| | | item.showPopUp = true |
| | | }) |
| | | item.showPopUp = true; |
| | | }); |
| | | this.popupNewsList = list |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | closePopNotice(item) { |
| | | item.showPopUp = false |
| | | setStorage('popNotice', true) |
| | | item.showPopUp = false; |
| | | setStorage('popNotice', true); |
| | | }, |
| | | toAnnounceDetail(announceId) { |
| | | if (announceId) { |
| | | this.$router.push({ path: '/cryptos/AnnounceDetail', query: { id: announceId } }) |
| | | this.$router.push({ path: '/cryptos/AnnounceDetail', query: { id: announceId } }); |
| | | } |
| | | }, |
| | | onClickLeft() { }, |
| | | onClickRight() { }, |
| | | startTimeout() { |
| | | this.clearTimeout() |
| | | this.fetchQList() |
| | | this.clearTimeout(); |
| | | this.fetchQList(); |
| | | }, |
| | | clearTimeout() { |
| | | if (this.timeout) { |
| | | clearTimeout(this.timeout) |
| | | this.timeout = null |
| | | clearTimeout(this.timeout); |
| | | this.timeout = null; |
| | | } |
| | | } |
| | | }, |
| | | async created() { |
| | | this.getNews(); |
| | | this.getPopupNews() |
| | | await this.SET_COIN_LIST('cryptos') |
| | | this.startTimeout() |
| | | this.getPopupNews(); |
| | | this.startTimeout(); // 优先执行缓存加载 |
| | | await this.SET_COIN_LIST('cryptos'); |
| | | // 缓存已加载,重新计算hList |
| | | if (this.qList && this.qList.length) { |
| | | this.hList = this.qList.filter(item => this.hotArr.includes(item.symbol)).slice(0, 3); |
| | | } |
| | | }, |
| | | async activated() { |
| | | this.getNews() |
| | | this.getPopupNews() |
| | | await this.SET_COIN_LIST('cryptos') |
| | | this.startTimeout() |
| | | this.getNews(); |
| | | this.getPopupNews(); |
| | | this.startTimeout(); // 优先执行缓存加载 |
| | | await this.SET_COIN_LIST('cryptos'); |
| | | // 缓存已加载,重新计算hList |
| | | if (this.qList && this.qList.length) { |
| | | this.hList = this.qList.filter(item => this.hotArr.includes(item.symbol)).slice(0, 3); |
| | | } |
| | | if (this.userInfo.token) { |
| | | this.fetchUnread() |
| | | this.unreadMsg_timer = setInterval(() => { this.fetchUnread() }, 5000); |
| | | this.fetchUnread(); |
| | | this.unreadMsg_timer = setInterval(() => { this.fetchUnread(); }, 5000); |
| | | } else { |
| | | this.unreadMsg_num = '' |
| | | this.unreadMsg_num = ''; |
| | | } |
| | | }, |
| | | deactivated() { |
| | | this.clearTimeout() |
| | | this.clearTimeout(); |
| | | if (this.unreadMsg_timer) { |
| | | clearInterval(this.unreadMsg_timer); |
| | | this.unreadMsg_timer = null; |
| | | } |
| | | }, |
| | | beforeUnmount() { |
| | | this.clearTimeout() |
| | | this.clearTimeout(); |
| | | if (this.unreadMsg_timer) { |
| | | clearInterval(this.unreadMsg_timer); |
| | | this.unreadMsg_timer = null; |
| | |
| | | } |
| | | |
| | | span { |
| | | color: $text_color1;; |
| | | color: $text_color1; |
| | | ; |
| | | font-size: 22px; |
| | | line-height: 30px; |
| | | } |
| | |
| | | height: 40px !important; |
| | | margin-top: 8px; |
| | | } |
| | | .content-title{ |
| | | font-size: 28px; |
| | | |
| | | .content-title { |
| | | font-size: 28px; |
| | | } |
| | | </style> |