携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
之前我负责的页面实现了通过点击不同的 tab 标签页跳转到不同的页面(注意这里并非通过改访问 url,只是在一个打的页面中,套了两个页面,点击不同的 tab 标签激活对应的页面)。但这存在一个问题,如果我点击并不是第一次加载时,默认加载的页面,刷新后,就会自动跳回默认的页面,不会保持在本页面。
问题
如上面所述,利用 tab 标签进行页面切换代码块如下:
<template>
<el-tabs v-model="activePage" @tab-click="tabClick(activePage)">
<el-tab-pane label="页面一" name="page1"></el-tab-pane>
<el-tab-pane label="页面二" name="page2"></el-tab-pane>
</el-tabs>
</template>
...
//展示嵌套页面
<component v-bind:is="showSee"></component>
而我在页面初次加载时默认加载页面一:
export default {
name: "XXX"
data() {
return {
activePage: 'page1',
showSee: null,
}
}
}
而点击事件 tabClick 逻辑如下:
tabClick(val) {
if (val == 'page1') {
this.showSee = page1;
} else if (val == 'page2') {
this.showSee = page2;
}
}
此外,钩子函数 mounted 每次都会自动执行 tabClick,如下:
mounted: function() {
this.tabClick(this.activePage);
}
这样写,就会导致每次刷新页面时,因为 activePage 默认设为了 page1,所以都会自动加载page1,即使你当时是在page2。
解决思路
之前是没用到 url,不管加载哪个子页面,访问路径都是直接 ip + 端口,思路就是在 url 上将不同页面区分开来,每次刷新,会根据 url 中的标识加载对应子页面。至于 url 上的标识可以通过路由对象获取。
实现
需要另写一个方法,用于更新中间标识:
updateType() {
let type = this.route.query.type;
if (type === '1') {
this.activePage = 'page1';
} else if (type === '2') {
this.activePage = 'page2';
}
//然后再调用点击事件
this.tabClick(this.activePage);
}
同时,tab 点击事件也要改动一下,因为涉及到不同页面 type 的值不同:
async tabClick(val) {
let queryType;
if (val == 'page1') {
this.showSee = page1;
queryType = '1';
} else if (val == 'page2') {
this.showSee = page2;
queryType = '2';
}
await this.$router.push({
query: {
type: queryType || '1'
}
});
}
此外,钩子函数 mounted 中也有所变化:
mounted: function() {
//页面一加载,首先执行一次 updateType() 方法
//挂载时通过 this.$route.query.type 拿到 url 后 type 的值
this.updateType();
}
这样的话,在点击不同的 tab 标签时,url 中会带上 ...?type=1 或者 ...?type=2,根据 url 中 type 的不同,就可以保证刷新页面前,从 route 对象中取到当前是在哪个页面,刷新后仍然在该页面。
补充
这样的写法,控制台可能会报错(我遇到了)。错误信息类似 Uncaught (in promise) NavigationDuplicated {_name: 'NavigationDuplicated', name: 'NavigationDuplicated', message: 'Navigating to current location ("/?type=1") is not allowed', stack: 'Error/n'} at new NavigationDuplicated......
解决方法:在 main.js 中加上如下设置:
import Router from 'vue-router'
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
我在 main.jc 中加了这一段后,控制台就没报错了。
这个“刷新保持在当前页”问题也是困扰了我好一段时间,虽然最后也是《某度》的,但我的这个实现跟当时看的文章情况不太一样,那篇文章算是给了我解决的思路。也希望我这篇文章能够帮到你。
有错误,望指正!
我向你敬礼啊,Salute!