【问题标题】:Vue i18n - adding locale to the URL using routerviewVue i18n - 使用 routerview 将语言环境添加到 URL
【发布时间】:2018-12-06 12:30:12
【问题描述】:

我正在使用带有 VueJS 和 TypeScript 的支架式 AspNetCore 2.1 站点。 我正在尝试将kazupon i18n 插件与路由器视图集成。如果没有 URL 集成,它就可以正常工作。

我无法像http://localhost/en/producthttp://localhost/fr/product 那样进行正确的重定向

这是最初的boot.ts,它使用VueI18n

import Vue from 'vue';
import VueRouter from 'vue-router';
import VueI18n from 'vue-i18n'

Vue.use(VueRouter);
Vue.use(VueI18n);

import { messages, defaultLocale } from './lang/i18n';

const i18n = new VueI18n({
    locale: defaultLocale,
    fallbackLocale: 'en',
    messages
})

const routes = [
        { path: '/', component: require('./components/home/home.vue.html') },
        { path: '/product', component: require('./components/product/product.vue.html') },
];

const router = new VueRouter({
    mode: 'history',
    routes: routes
});

new Vue({
    el: '#app-root',
    router: router,
    i18n: i18n,
    render: h => h(require('./components/app/app.vue.html'))
});

到目前为止,我已经尝试为 routes 添加前缀,但它只是破坏了功能:

const routes = [{
    path: '/',
    redirect: `/${defaultLocale}`,
},
{
    path: '/:locale',
    children: [
        { path: '/', component: require('./components/home/home.vue.html') },
        { path: '/counter', component: require('./components/product/product.vue.html') },
    ]
}];

我也尝试过依靠router.beforeEach 来设置语言环境。

router.beforeEach((to, from, next) => {
    let language = to.params.locale;
    if (!language) {
        language = 'en';
    }

    i18n.locale = language;
    next();
});

这也不起作用。

我从github.com/ashour/vuejs-i18n-demovue-i18n-sap-multilingual-best-practice 中汲取了灵感,但似乎在 i18n 迁移期间,一些示例可能已经过时或丢失,并且这些用例不再起作用。

【问题讨论】:

  • 请注意,在带有路径的示例中:'/:locale' 您缺少component: { template: '<router-view />', }, 元素。我的意思是像here

标签: vue.js internationalization vuejs2 vue-router


【解决方案1】:

您主要需要的是在 vue-router 构造函数中指定 base 选项。

但首先,您需要从 url 中提取语言环境:

let locale = window.location.pathname.replace(/^\/([^\/]+).*/i,'$1');

然后在VueRouter 构造函数中指定base

const router = new VueRouter({
    ...
    base: (locale.trim().length && locale != "/") ? '/' + locale : undefined
    ...
});

最后但并非最不重要的一点是,将语言环境传递给您的 VueI18n 构造函数:

const i18n = new VueI18n({
    locale: (locale.trim().length && locale != "/") ? locale : defaultLocale,
    fallbackLocale: 'en',
    messages
})

查看更新示例:

import Vue from 'vue';
import VueRouter from 'vue-router';
import VueI18n from 'vue-i18n'

Vue.use(VueRouter);
Vue.use(VueI18n);

import { messages, defaultLocale } from './lang/i18n';

var locale = window.location.pathname.replace(/^\/([^\/]+).*/i,'$1');


const i18n = new VueI18n({
    locale: (locale.trim().length && locale != "/") ? locale : defaultLocale ,
    fallbackLocale: 'en',
    messages
})

const routes = [
        { path: '/', component: require('./components/home/home.vue.html') },
        { path: '/product', component: require('./components/product/product.vue.html') },
];

const router = new VueRouter({
    base: (locale.trim().length && locale != "/") ? '/' + locale : undefined,
    mode: 'history',
    routes: routes
});

new Vue({
    el: '#app-root',
    router: router,
    i18n: i18n,
    render: h => h(require('./components/app/app.vue.html'))
});

【讨论】:

  • 我不太明白你的意思。你的意思是像http://localhost/ 而不是http://localhost/en
  • 是的,这将解决它。
  • 更新基础,base: (locale.trim().length && locale != "/") ? '/' + locale : undefined,
  • 另外,您不应该将 defaultLocale 分配给语言环境,因为它会影响我上面提到的 base 选项的条件。你应该做locale : locale.trim().length && locale != "/" ? locale : defaultLocale
  • 嗨@Ovi,请不要忘记将此标记为答案:) 很高兴与您交谈!
【解决方案2】:

非常感谢@Julian Paolo Dayag,我的问题中的方法存在三个问题:

  1. 它需要重定向到"/" + defaultLocale + to.path
  2. 子路由不应该以/开头,它们应该是product而不是/product
  3. 不再需要router.beforeEach...

我最终得到了这段代码:

const routes = [
  {
    path: "/",
    redirect: `/${defaultLocale}`
  },
  {
    path: `/(fr|en)`,
    component: require("./components/app/routertemplate.vue.html"),
    children: [
      { path: "", component: require("./components/home/home.vue.html") },
      {
        path: "product",
        component: require("./components/product/product.vue.html")
      }
    ]
  },
  {
    path: "/(.*)",
    redirect: (to: any) => {
      return "/" + defaultLocale + to.path;
    }
  }
];

【讨论】:

  • routertemplate.vue.html 里面有什么?
  • @tomfl 我猜只是一个简单的<router-view /> 来渲染嵌套路径,请参阅official docs
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2021-08-15
  • 2019-12-17
  • 2021-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多