Заставьте VueI18n среагировать на тег ссылки роутера

У меня есть это приложение Vue, которое состоит из простой домашней страницы, заголовка и домашнего текста. Вы можете просмотреть это приложение онлайн на моем JSFiddle. Вот код:

HTML

<div id="app">
  My header app
  <router-view></router-view>
</div>

JavaScript

const Home = {
    template: `
      <div>
        <h1>{{ $t('home.title') }}</h1>
        <p v-html="$t('home.text')"></p>
      </div>
    `
};

const messages = {
    en: {
    home: {
        title: 'Hello world',
        text: 'Find all post by clicking <router-link to="/post">this link</router-link>!'
    }
  }
};

const routes = [
    { name: 'home', path: '*', component: Home }
];

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

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

const vue = new Vue({
    el: '#app',
    router: router,
    i18n: i18n
});

проблема

Как видите, ссылка "router-link" не видна, и нажатие на ссылку не приведет к перенаправлению на нужный маршрут.

Вопрос

Можно ли заставить VueI18n интерпретировать <router-link> тег внутри v-html Директива?

2 ответа

Решение

v-html заменяет содержимое элемента простым HTML, поэтому пользовательские элементы, используемые внутри замещающей строки, не компилируются в компоненты Vue.js.

Вы можете проверить способ интерполяции компонентов, предложенный документацией VueI18n, который включает использование i18n функциональный компонент и шаблон строки.

Вот форк предоставленной скрипки, который реализует этот подход: http://jsfiddle.net/u5vx1mLq/

В двух словах, i18n компонент имеет path опора, в которой вы можете найти путь к строке шаблона и tag опора, которая определяет тег, i18n компонент должен быть заменен на. i18n также есть слот, который можно использовать для определения дочернего компонента, в котором вы можете интерполировать частичные строки шаблона.

Извините за неловкое объяснение, надеюсь, фрагмент кода поможет пролить свет на этот вопрос:

const Home = {
  template: `
    <div>
      <h1>{{ $t('home.title') }}</h1>
      <i18n path="home.linkLabel" tag="label" for="home.linkText">
        <router-link to="/post">{{ $t('home.linkText') }}</router-link>
      </i18n>
    </div>
  `
};

const messages = {
  en: {
    home: {
      title: 'Hello world',
      linkText: 'this link',
      linkLabel: 'Find all post by clicking {0}'
    }
  }
};

Несколько вещей изменилось с момента отличного ответа Антонку

https://vue-i18n.intlify.dev/guide/advanced/component.html

Тег вроде

      <i18n-t keypath="mymessage">xxx</i18n-t>

выведет переводmymessageиxxxотправляется в качестве параметра для этого сообщения

      const messages = {
  en: {
    mymessage: 'here are some characters: {0}'
  }
};

Более сложный, этот тег принимает две ссылки в качестве входных данных и отображает выходные данные в видеsmallярлык

      <i18n-t keypath="twolinks" tag="small">
   <template v-slot:link1>
     <a href="//link1.nl/" target="_blank">here</a>
   </template>
   <template v-slot:link2>
     <router-link :to="{ name: 'login' }">here</router-link>
   </template>
</i18n-t>
      const messages = {
  en: {
    twolinks: 'I want you to click {link1} and then {link2}'
  }
};
Другие вопросы по тегам