基于Vue-Router语言的路由前缀

时间:2019-08-12 14:29:59

标签: vue.js vuejs2 vue-router vue-i18n

我使用$created_request->json()->all()来渲染某些页面,以便从Vue应用中获得更好的SEO。

我的目标是改变目前使用prerender-spa-plugin的方式,因此我可以将其基于url参数Vue-i18n。示例:/lang/en/home。有了这个,我将能够根据语言进行预渲染。

我创建了一个前缀函数,将可选参数/nl/home添加到每个父路由。在这里:

/:lang?

在Vue模板中,我正在使用:

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;
});

因此,我试图根据<router-link :to="`/account`"> 参数将重定向重定向到下一个页面。

第一种方法

最合乎逻辑的是(在路由器的lang内部):

beforeEach

但是它进入了一个无限循环,因为from总是一样。

第二种方法

使用const { lang } = to.params; const redirectTo = lang ? to.fullPath : `${fullToLang}${to.fullPath}`; if (from.fullPath !== redirectTo) { next({ path: redirectTo }); } else { next(); } 的{​​{1}}属性。

Router

或者更好,活着: https://codesandbox.io/embed/vue-template-0bwr9

但是,仅在路由中未找到网址时,我才不理解为什么将其重定向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"); 时都必须创建一个新的/en/nope实例吗?

第三种方法

用于Router基于base注入router-link的包装器组件。

这将在加载应用程序后进行导航,但不会在第一次刷新/初始化时进行。

那么,我该如何解决呢?

解决方案

是的,第一种方法是正确的方法,但是我误解了Router在:tothis.$route.params.lang的情况下的行为。条件应该是检查next而不是redirects

to

2 个答案:

答案 0 :(得分:1)

我不确定您要问什么。但是我假设您要在导航中添加当前语言参数(../en/ ..)的前缀(如果它们还没有)?

您可以使用beforeEach()钩子解决此问题,并且仅在不存在lang参数的情况下进行重定向。

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

如果这不是您想要的,请澄清,我将编辑答案

答案 1 :(得分:0)

是这样吗?假设新路径以/[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>

相关问题