簡體   English   中英

基於Vue-Router語言的路由前綴

[英]Vue-Router language based route prefix

我正在使用prerender-spa-plugin來預呈現某些頁面,以便從我的Vue應用程序中獲得更好的SEO。

我的目標是改變我目前使用Vue-i18n ,所以我可以將它建立在url param /lang 示例: /en/home/nl/home 有了這個,我就可以根據語言進行預渲染。

我創建了一個前綴函數,它為每個父路由添加了可選的param /: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 param操縱重定向下一頁

第一種方法

最合乎邏輯的是(在Router的beforeEach ):

const { lang } = to.params;
const redirectTo = lang ? to.fullPath : `${fullToLang}${to.fullPath}`;
if (from.fullPath !== redirectTo) {
  next({ path: redirectTo });
} else {
  next();
}

但它進入無限循環,因為從始至終都是一樣的。

第二種方法

使用Routerbase屬性。

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 (最后一種情況)。 而且,每次我想要更改base時,我是否必須創建一個新的Router實例?

第三種方法

router-link注入的包裝組件:to基於this.$route.params.lang

這將在加載應用程序后進行導航,但不會在第一次刷新/初始化時進行導航。

那么,我該如何解決這個問題呢?

解決方案

所以是的,第一種方法是正確的方法,但我很想念路由器如何處理nextredirects 條件應該是檢查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;
}

我不完全確定你在問什么。 但是我假設您想要使用當前語言參數(../en/ ..)為您的導航添加前綴,如果它們還沒有?

您可以使用beforeEach()鈎子解決此問題,並且只有在沒有lang param存在的情況下才會重定向。

const { lang } = to.params
if(!lang) {
  next({ path: redirectTo })
}
next()

如果這不是你想要的,請澄清,我會編輯我的答案

像這樣的東西? 假設新路徑開始/[lang]/...

作為注釋 - 在路由例如/:lang/bar - > /foo/bar時仍然存在錯誤

 Vue.lang = 'en' function beforeEnter(to, from, next){ if ((new RegExp(`^/${Vue.lang}$`)) .test(to.path) || (new RegExp(`^/${Vue.lang}/`)) .test(to.path)) { next(); } else { next({path: `/${Vue.lang}${to.path}`}) } }; Vue.mixin({ beforeRouteEnter: beforeEnter }) const Foo = { template: '<div>foo - {{$route.path}}</div>' } const Bar = { template: '<div>bar - {{$route.path}}</div>' } const Root = { template: '<div>Root - {{$route.path}}</div>' } const Invalid = { template: '<div>404</div>' } const routes = [ { path: '/:lang/foo', component: Foo }, { path: '/:lang/bar', component: Bar }, { path: '/:lang/*', component: Invalid }, { path: '/:lang', name: 'Home', component: Root }, // some weird issue that prevents beforeRouteEnter ? so redirect, but else next is needed { path: '/', redirect: to => `/${Vue.lang}`} ] const router = new VueRouter({ routes }) new Vue({ data(){ return { pLang: Vue.lang, } }, computed: { lang: { get(){ return this.pLang }, set(val){ Vue.lang = val this.pLang = val } } }, router, }).$mount('#app'); 
 <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <div id="app"> <h1>Hello App!</h1> <p> {{lang}} <select v-model="lang"> <option value="en">en</option> <option value="cn">cn</option> </select> <!-- use router-link component for navigation. --> <!-- specify the link by passing the `to` prop. --> <!-- `<router-link>` will be rendered as an `<a>` tag by default --> <router-link to="/">Root</router-link> <router-link to="/foo">Go to Foo</router-link> <router-link to="/bar">Go to Bar</router-link> <router-link to="/foo/bar">Go to Foo/Bar - not defined</router-link> </p> <!-- route outlet --> <!-- component matched by the route will render here --> <router-view></router-view> </div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM