我在做页面的时候发现,当跳转到另一个页面的时候,由于两个页面复用了一个相同的子组件,导致新页面不会重新渲染子组件部分。
组件复用了所以不会重新渲染。
举例:
子组件:(随意写了)
Box.vue
<div>
<input type="text" name="usename" />
<label for="username"></label>
</div>
第一个父组件引入子组件
Home.vue
<div class="home_container>
<div class="title">Home</div>
<Box></Box>
</div>
第二个父组件引入子组件
Book.vue
<div class="book_container>
<div class="title">Book</div>
<Box ref="box"></Box>
</div>
如果从Home页面跳到Book页面,Box就不会重新渲染,也就是当你想在book里面通过this.refs.box获取Box元素是获取不到的,因为Box没有重新渲染,所以还是原来Home页面的Box,没有ref属性。
解决办法:
-
强制更新
vm.$forceUpdate() -
v-if
// 父组件 Book.vue
<Box v-if="reRender"></Box>
// 第一种:监听数据变化,先销毁当前组件,再重新渲染。
data(){
return {
reRender:true
}
}
watch:{
handle(){
this.reRender = false
this.$nextTick(()=>{
...
this.reRender = true
})
}
}
//第二种:监听路由变化,重新渲染
data(){
return {
reRender:false
}
}
watch:{
$route(){
this.reRender = true
}
}
- 给组件加个key
举例:
这里结合了父组件传值给子组件
// 子组件
<div :key="keys">
<input type="text" name="usename" />
<label for="username"></label>
</div>
props:{
keys:{
type:String,
required:true
}
}
// 父组件 Book.vue
<Box keys="book"></Box>
- 刷新整个页面
// 第一种
location.reload()
// 第二种
this.$router.go(0)
最后我的页面直接添加key解决了。给个key最方便了。
这就是vue种key的原理。
加key能够会标识组件的唯一性,更好的区别每个组件。
不加key的话节点会复用,省去了销毁/创建组件的开销,同时只需要修改DOM文本内容而不是移除/添加节点。