最近用iview-admin做后台管理系统,遇到了个问题,列表页面点击进入详情页面编辑,编辑完成自动跳转到列表页,需要页面重新刷新请求列表(后管就是这么简单粗暴),然并卵~,再次回到列表页页面不会重新刷新;问题很好解决,因为iview-admin的路由设置会默认缓存页面notCache:false,因此我直接设置notCache:true就ok了,页面可以重新刷新。但是我觉得这个问题简单也不简单;
vue-router的切换不同于传统的页面的切换,路由之间的切换,其实就是组件之间的切换,不是真正的页面切换。这也会导致一个问题,就是引用相同组件的时候,会导致该组件无法更新,也就是我们口中的页面无法更新的问题了,这是根源;
所以参考网上一些文章加上自己之前遇到过得一些相似问题小结一下;
针对不同的需求分为两部分:
场景:(vue-cli生成的项目)
分析问题:
解决问题:
容器组件,将页面缓存起来;
是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。具体代码:
routes: [
{
path: 'index/query',
component: ()=>import('@/components/data_center/xxx/index.vue'),
meta: {
keepAlive: true, // 是否缓存
scollTopPosition: 0 // 滚动条位置
}
}
]
// 不!能!获取组件实例 `this`
beforeRouteEnter(to, from, next) {
next(vm => {
if (from.path === "xxx") {
document.getElementById('home_query').scrollTop = to.meta.scollTopPosition;
}
});
},
beforeRouteLeave(to, from, next) {
if(from.meta.keepAlive) {
from.meta.scollTopPosition = document.getElementById('home_query').scrollTop;
}
next();
}
vm.$set(vm.array,index,newValue)
vm.array.splice(index,1,newValue)
PS: 如何在vue中实时查看滚动条,滚动的位置的值?
mounted() {
// 监听window中滚动条的位置
window.addEventListener('scroll', function(){
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
console.log(scrollTop);
});
// 监听指定某个元表滚动条的位置
document.querySelector('#listBox').addEventListener('scroll', function(){
let scrollTop = this.pageYOffset || this.scrollTop;
console.log(scrollTop);
}
在解决这个问题之前先说一下
这个组件,其实在上面页面后退不刷新的解决方案里面会用这个组件也是最重要的;
keep-alive理解:
在平常开发中,有部分组件没有必要多次初始化,这时,我们需要将组件进行持久化,使组件的状态维持不变,在下一次展示时,也不会进行重新初始化组件。
也就是说,kee-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免DOM重新渲染 。也就是所谓的组件缓存。
开启keep-alive之后页面生命周期钩子函数执行顺序:页面第一次进入created—mounted—activated,退出时触发deactivated。当再次进入时,只触发activated;
场景:
解决问题:
meta: {
keepAlive: false, // 是否缓存
}
// iview-admin
meta: {
icon: 'md-apps',
title: '动态详情',
hideInMenu: true,
notCache: true //关闭缓存
},
官方提供的解决方案为要对同一组件更改做出反应,监听$route的变化,或者使用使用2.2中引入的beforeRouteUpdate
导航卫士,调用对应的方法。
// 监控路由中的数据变化
watch: {
$route(to, from) {
if (this.$route.query.id) {
console.log( "获取页面数据" );
}
}
},
// 或者使用beforeRouteUpdate 导航守卫监听路由变化
beforeRouteUpdate(to, from, next) {
console.log(this.$route.query.id);
if (this.$route.query.id) {
console.info("获取页面数据");
}
next();
},
注意:
如果想强制刷新,可以在根路由上为其分配一个唯一key。采用$route.fullpath作为其唯一key。这样vue就回认为内部路由每个都是不同的路由,在跳转时便会强制刷新组件。
这时候路由就会更新了。不过这也就意味着需要把每个都绑定一个key值。如果我从page1跳到page2不同组件的话,我其实是不用担心组件更新问题的。
给
增加一个不同v-if值,来先摧毁,然后再重新创建起到刷新页面的效果。
provide和inject
名字:
this.$router.go(-1)
或this.$router.back()
。本文参考:参考