vue中使用了v-if,内容出现了闪现然后消失
问题及基本代码
目标效果:当访问的路径是need时就隐藏顶部的common组件
具体问题:访问 http://localhost:8080/#/need,每次刷新页面顶部都会闪现一下蓝色的盒子(common.vue)
相关路由:
{
path: '/need',
name: 'need',
component: () => import('../views/need.vue')
}
根组件App.vue
<template>
<div id="app">
<common v-if="$route.name !== 'need'"></common>
<router-view></router-view>
</div>
</template>
<script>
import common from './components/common.vue'
export default {
components: {
common: common
}
}
</script>
common.vue是一个蓝色的盒子
<template>
<div class="common">
<div style="backgroundColor:green;height200px;">common组件</div>
</div>
</template>
need.vue组件
<template>
<div class="father">
<h1>这是need组件</h1>
</div>
</template>
解决思路
访问这个路由的时候,当前路由 route.name===‘name’,所以v-if=“false”;应当不会闪现;组件应该都不会被创建
实际上每次初始化的时候,common组件都会渲染一次;
方案1: 我想先将组件隐藏,让他一开始就不出现;后面再去根据 $route.name判断,应该就好了
<common
class="hideBox"
:class="{ showBox: $route.name !== 'need' }"
></common>
.hideBox {
display: none;
}
.hideBox.showBox {
display: block;
}
结果发现不行,还是会闪现;难道时v-if不显示的话会先渲染再隐藏?还是 $route.name !== ‘need’ 这个条件一开始一定时true,然后再变为false
于是我就在app.vue中打印了一下this.$route.name
created() {
console.log('created1', this.$route.name) // null
},
mounted() {
console.log('mounted1', this.$route.name) // null
},
updated() {
console.log('updated1', this.$route.name) // need
}
结果发现app.vue中created和mountd都没有拿到期待的值
但是我之前也使用过,用$router.name来判断,没出现问题;于是我在need.vue中也添加了一个相同判断,且在这三个声明周期中打印
修改后的need.vue部分代码
<h1>这是need组件</h1>
<div v-if="$route.name !== 'need'">
<div style="height:200px;backgroundColor:red"></div>
</div>
created() {
console.log('created2', this.$route.name) // need
},
mounted() {
console.log('mounted2', this.$route.name) // need
},
updated() {
console.log('updated2', this.$route.name)
},
结果:刷新时只出现common.vue的闪现,加的测试的红色盒子并没闪现;created和mounted打印出了need
方案2:按需导入
再created之前就能判断它(common组件)不渲染
修改后app.vue的部分代码
<div id="app">
<common v-if="$route.name !== 'need'"></common>
<router-view></router-view>
</div>
components: {
common: () => import('./components/common.vue')
}
问题解决了,刷新不会闪现
编译的时候就不会导入这个组件了,自然不会渲染(need这个路径)
结论
v-if如果为false的话,确实不会先渲染再消失,false都不会生成对应dom
vue生命周期:父组件created=>父组件mounted=>子组件created=>子组件mounted=>父组件updated
再子组件mounted之前,app根组件是拿不到子组件的name, $route.name为null
vue组件尽量使用按需加载
e都不会生成对应dom
vue生命周期:父组件created=>父组件mounted=>子组件created=>子组件mounted=>父组件updated
再子组件mounted之前,app根组件是拿不到子组件的name, $route.name为null
vue组件尽量使用按需加载