这个需求是很常见的。
方法一:
1、先定义路由时添加关键字
{
path: "/",
component: Layout,
redirect: "/home",
children: [
{
path: "home",
name: "Home",
meta: {
keepAlive: true
},
component: () => import("@/views/Home.vue")
},
{
path: "about",
name: "About",
component: () => import("@/views/About.vue")
}
]
},
需要缓存的设置keepAlive: true
2、在路由切换容器设置
<keep-alive>
<router-view v-if="$route.meta.keepAlive" :key="key"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive" :key="key"></router-view>
3、在详情页面通过this.$router.back()来实现返回。不能push。
方法二:
1、定义路由时添加meta scrollToTop: false/true来表示需不需要缓存
{
path: "/",
component: Layout,
redirect: "/home",
children: [
{
path: "home",
name: "Home",
meta: {
scrollToTop: false
},
component: () => import("@/views/Home.vue")
},
{
path: "about",
name: "About",
component: () => import("@/views/About.vue")
}
]
},
{
path: "/article-edit",
component: Layout,
redirect: "/article-edit/index",
children: [
{
path: "index",
name: "ArticleEdit",
meta: {
scrollToTop: true
},
component: () => import("@/views/ArticleEdit.vue")
}
]
},
2、路由切换容器设置keep-alive
<transition name="fade-transform" mode="out-in">
<keep-alive>
<router-view :key="key"></router-view>
</keep-alive>
</transition>
3、在vuex中记录滚动条位置
const state = {
scrollTop: 0
};
const mutations = {
RECORD_SCROLL_TOP: (state, n) => {
state.scrollTop = n;
}
};
const actions = {
changeScrollTop({ commit }, num) {
commit("RECORD_SCROLL_TOP", num);
}
};
export default {
namespaced: true,
state,
mutations,
actions
};
4、在路由导航卫士做判断
import router from "./router";
import store from "./store";
import { getToken } from "@/utils/auth"; // 从cookie中拿去token
router.beforeEach((to, from, next) => {
// 要离开页面如果设置为不滚回到顶部,则本页是要记住上滚动高度到vuex中,以便下次进来恢复高度
if (from.meta.scrollToTop == false) {
store.dispatch("app/changeScrollTop", document.documentElement.scrollTop);
}
const hasToken = getToken();
if (hasToken) {
/* 有token */
if (to.path === "/login/index") {
// 有token,请求的是登录页面,直接返回首页
next({ path: "/home" });
} else {
next();
}
} else {
/* 无token */
if (to.meta.requireAuth) {
// 该路由需要登录权限
if (store.state.user.token) {
// vuex state中获取到当前的token是否存在
next();
} else {
next({
path: "/login"
// query: { redirect: to.fullPath } // 将跳转的路由path作为参数,登录成功后跳转到该路由
});
}
} else {
// 该路由不需要登录权限
next();
}
}
});
router.afterEach(to => {
// 如果进入后的页面是要滚动到顶部,则设置scrollTop = 0
//否则从vuex中读取上次离开本页面记住的高度,恢复它
if (to.meta.scrollToTop == true) {
setTimeout(() => {
document.documentElement.scrollTop = 0;
}, 10);
} else {
setTimeout(() => {
document.documentElement.scrollTop = store.state.app.scrollTop;
}, 50);
}
});
参考连接:
https://www.cnblogs.com/vbyzc/p/9952550.html
https://blog.csdn.net/zjl516088421/article/details/77937440
方法三、在2的思路上调整修改。
方法2还是有点问题。感觉不是很好操作。特麻烦,并且,有时候,反正测试,还是有点问题。
不需要在路由内定义,也不需要在路由导航中进行判断。
1、在vuex中定义保存scrollTop的值和触发方法。
2、在list页面中,点击详情跳转时,触发记录scrollTop的方法,然后跳转到详情页面去了。
handleRead(v) {
// console.log(document.body.scrollTop);
// console.log(document.documentElement.scrollTop);
this.$store.dispatch(
"app/changeScrollTop",
document.documentElement.scrollTop
);
this.$router.push({
path: "/article-detail/index",
query: { id: v._id }
});
},
3、在list页面,activated()钩子函数内,设置应该距离顶部导航的值
mounted() {},
activated() {
// console.log(this.$route);
// 需要刷新,keepalive不应该生效
if (this.$route.query.reload && this.$route.query.reload === true) {
this.fetchList();
}
// console.log(this.$store.state.app.scrollTop);
document.documentElement.scrollTop = this.$store.state.app.scrollTop;
},
methods: {}
4、如果在编辑页面跳转回来列表页面,需要页面刷新,就给路由传参,然后在activated中监听参数,看需不需要重新加载数据
articleAdd(para)
.then(() => {
this.$router.push({
path: "/home",
query: {
reload: true
}
});
})
注意,获取scollTop值的元素,有些元素的值,始终是0;监听获取的适合,需要注意一下。