问题:
在vue中页面使用了动态组件组件导致首次页面加载时子组件样式不显示,刷新后才正常。
原因:
因为动态组件的延迟加载,如果使用了Vue的动态组件(如
<component :is="...">
),可能会导致初次加载时CSS样式未正确应用。
<template>
<div>
<!-- top -->
<div class="knowledge-top">
<div class="knowledge-top-text">
<h1>外贸知识</h1>
</div>
</div>
<!-- 中间块 -->
<div class="knowledge-content">
<!-- 左侧二级路由挂载 -->
<div class="knowledge-left">
<!-- 左边列表组件 -->
<component :is="showlist"></component>
</div>
<!-- 右侧子导航区域 -->
<div class="knowledge-right">
<!-- 子导航 -->
<div class="knowledge-right-nav">
<h4>>> 外贸知识</h4>
<ul>
<li>
<img src="@/assets/icon/facebook.png" alt="">
<p @click="navigateTo('FacebookArt')">Facebook营销</p>
</li>
<li>
<img src="@/assets/icon/google.png" alt="">
<p @click="navigateTo('GoogleArt')">Google营销</p>
</li>
<li>
<img src="@/assets/icon/linkedin.png" alt="">
<p @click="navigateTo('LinkedInArt')">LinkedIn营销</p>
</li>
<li>
<img src="@/assets/icon/whatapp.png" alt="">
<p @click="navigateTo('WhatsAppArt')">WhatsApp营销</p>
</li>
</ul>
</div>
<!-- 热门文章 -->
<div class="knowledge-right-hot">
<div class="hot-art-title">
<h4>>> 近期热门文章</h4>
</div>
<div class="art-box">
<div class="art-item-box">
<div class="art-item" v-for="(art, index) in paginatedArtList" :key="index">
<a :href="art.artsrc">
<img :src="art.imgsrc" alt="">
<p>{{art.title}}</p>
</a>
</div>
</div>
<div class="fenyeqi-box">
<!-- <span class="demonstration">大于 7 页时的效果</span> -->
<el-pagination
layout="prev, pager, next"
v-model="currentPage"
:page-count="totalPages"
@current-change="handleCurrentChange"> <!-- 监听页码变化事件 -->
</el-pagination>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import FacebookArt from './FacebookArt.vue';
import GoogleArt from './GoogleArt.vue';
import LinkedInArt from './LinkedInArt.vue';
import WhatsAppArt from './WhatsAppArt.vue';
export default {
name: "Knowledge",
data() {
return {
currentPage: 0, // 当前页码
showlist:'FacebookArt',
isShowHf:true,
};
// artList:[]
},
components:{
FacebookArt,
GoogleArt,
LinkedInArt,
WhatsAppArt,
},
computed: {
artList() {
return this.$store.state.CurrentArt;
},
paginatedArtList() {
const start = this.currentPage * 3;
const end = start + 3;
return this.artList.slice(start, end);
},
totalPages() {
// 计算总页数
return Math.ceil(this.artList.length / 3); // 每页显示6条数据
},
},
methods: {
handleCurrentChange(page) {
this.currentPage = page - 1; // ElementUI 分页器从 1 开始,而我们的计算从 0 开始,需要转换一下
},
// currentPage(step = 1) {
// this.currentPage = Math.max(0, Math.min(this.currentPage + step, Math.ceil(this.artList.length / 2) - 1));
// }
navigateTo(path){
this.showlist = path;
console.log(this.showlist);
}
},
mounted(){
console.log(this.totalPages);
}
};
</script>
解决办法:
一、预加载组件,通过在`mounted`生命周期钩子中预加载所有动态组件,确保它们的CSS样式在初次加载时就已经应用。
mounted(){
console.log(this.totalPages);
// 预加载组件
FacebookArt();
GoogleArt();
LinkedInArt();
WhatsAppArt();
}
二、 避免CSS作用域问题,如果组件中的CSS使用了`scoped`属性,确保样式可以正确应用到子组件。不过要确保当前页面的css样式可以适用到子组件。
<style scoped>
/deep/ .child-component-class {
/* 样式规则 */
}
</style>
三、强制重绘,在组件加载后强制触发浏览器的重绘。
mounted() {
console.log(this.totalPages);
// 强制重绘
this.$nextTick(() => {
const el = this.$el.querySelector('.knowledge-left');
if (el) {
el.style.display = 'none';
el.offsetHeight; // 强制重绘
el.style.display = '';
}
});
}