这个问题其实已然不新鲜了,主要源于浏览器对直接输入的中文 url
做了一次 encode
导致 匹配不到 vue-router
对应的 path
要解决这个问题,可以参照 Pull requests
[1]
有了这层思路,问题也就不难得到解决。
方法1:纠正 router 的跳转
因为 vuepress
的机制问题,没有匹配到 layout
的 markdown
文件,最终会自动导向 404.vue
或者 NotFound.vue
。了解到这层后,我们可以直接在导向的终点对其进行操作。
mounted() {
let routes = [this.$author._metaMap, this.$tag._metaMap],
routeList = []; // 将所有包含中文需要重新匹配的 router path 写入一个数组中
routes.forEach((route) => { // 遍历将对象糅合成一个数组
Object.keys(route).forEach((key) => {
routeList.push(route[key].path);
});
});
if(routeList.includes(this.$route.params.pathMatch)){ // 判断是否存在当前 route ,存在则跳转
this.$router.push(this.$route.params.pathMatch)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Tips
this.$author._metaMap
与 this.$tag._metaMap
来源于 config.js
中的 frontmatters
; 参照 frontmatter-classifier (opens new window)
方法2:对
url
进行decode
// enhanceApp.js
import Router from 'vue-router'
import Vue from 'vue'
const router = new Router({
mode: 'history'
})
// 防止相同路由跳转时报错
const VueRouterPush = Router.prototype.push
Router.prototype.push = function push (to) {
return VueRouterPush.call(this, to).catch(err => err)
}
export default ({
Vue,
router
}) => {
router.beforeEach((to, from, next) => {
// 解决非ASCII文件名的路由, 防止 404
const decodedPath = decodeURIComponent(to.path)
if (decodedPath !== to.path) {
next(Object.assign({}, to, {
fullPath: decodeURIComponent(to.fullPath),
path: decodedPath
}))
} else {
next()
}
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30