【发布时间】:2019-12-19 03:33:42
【问题描述】:
我使用prerender-spa-plugin 来预渲染某些页面,以便从我的 Vue 应用程序中获得更好的 SEO。
我的目标是改变我目前使用Vue-i18n 的方式,所以我可以基于url 参数/lang。示例:/en/home 或 /nl/home。有了这个,我就可以根据语言进行预渲染。
我创建了一个前缀函数,它为每个父路由添加可选参数/:lang?。这里是:
const withPrefix = (prefix: string, routes: RouteConfig[]): RouteConfig[] => routes.map((route): RouteConfig => {
// Avoiding mutations
const clonedRoute = { ...route };
// Every route except for '/'
if (clonedRoute.path !== '/') {
clonedRoute.path = prefix + clonedRoute.path;
}
return clonedRoute;
});
在 Vue 模板中,我使用的是:
<router-link :to="`/account`">
所以我正在尝试根据lang 参数将 redirect 操作到 next 页面。
第一种方法
最合乎逻辑的是(在Router的beforeEach里面):
const { lang } = to.params;
const redirectTo = lang ? to.fullPath : `${fullToLang}${to.fullPath}`;
if (from.fullPath !== redirectTo) {
next({ path: redirectTo });
} else {
next();
}
但它进入了一个无限循环,因为 from 总是相同的。
第二种方法
使用Router 的base 属性。
import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import HelloWorld from "./components/HelloWorld";
import Test from "./components/Test";
Vue.config.productionTip = false;
Vue.use(VueRouter);
const router = new VueRouter({
mode: "history",
base: "/en",
routes: [
{
path: ":lang?/",
component: HelloWorld,
beforeEnter: (to, from, next) => {
console.log(1);
next();
}
},
{
path: "/:lang?/nope",
component: Test,
beforeEnter: (to, from, next) => {
console.log(2);
next();
}
},
{
path: "/:lang?/*",
beforeEnter: (to, from, next) => {
console.log(to);
next("/nope");
}
}
]
});
new Vue({
render: h => h(App),
router
}).$mount("#app");
或者更好,生活: https://codesandbox.io/embed/vue-template-0bwr9
但是,我不明白为什么它重定向到/en/nope,只有在路由上找不到url(最后一种情况)。而且,每次我想更改base 时,我是否必须创建一个新的Router 实例?
第三种方法
基于this.$route.params.lang 注入:to 的router-link 包装器组件。
这将在应用加载后进行导航,但不是在第一次刷新/初始化时。
那么,我应该如何解决这个问题?
~ 解决方案 ~
所以,是的,第一种方法是正确的方法,但我误解了路由器与 next 和 redirects 的行为方式。条件应该是检查to 而不是from。
const redirectTo = lang ? to.fullPath : `${fullToLang}${to.fullPath}`;
if (to.fullPath !== redirectTo) {
// Change language at i18n
loadLanguageAsync(toLang as Language);
next({ path: redirectTo });
return;
}
【问题讨论】:
标签: vue.js vuejs2 vue-router vue-i18n