Как заставить роутер-линк работать с пользовательским компонентом линков? - PullRequest
0 голосов
/ 05 июня 2018

<base-link> компонент

У меня есть компонент Vue <base-link>, который я использую каждый раз, когда хочу получить ахор.Это в основном для применения стилей, характерных для ссылок, так что все ссылки на всей странице выглядят одинаково без применения глобальных стилей.

Make <router-link> use <base-link>

При использовании <router-link> компонент для создания ссылки, я не могу применить эти стили (<base-link> стили ограничены), если <router-link> не использует мой <base-link> компонент для создания элемента привязки.

К счастью <router-link> предоставляет tag атрибут , который, кажется, делает именно это.К сожалению, я не могу заставить его работать.У меня 2 проблемы:

  1. Все мои компоненты зарегистрированы локально (я использую модули ES6 с Webpack и импортирую компоненты локально каждый раз, когда они мне нужны).<router-link> не знает, что такое <base-link> компонент, и не может его отобразить.Есть ли способ внедрить локальный компонент для использования <router-link>?

  2. Чтобы решить проблему # 1, я подумал, что достаточно объявить компонент <base-link> глобально.К сожалению, это все еще не работает.На этот раз <base-link> компонент отображается правильно, но все еще не функционирует - не реагирует на события нажатия.Мне кажется, проблема в том, что атрибут href вообще не установлен.Есть ли способ заставить <router-link> установить его правильно?(без настройки вручную)

Вопрос

Как решить проблемы № 1 и № 2?Я подозреваю, что # 1 может быть невозможным, но я надеюсь, что по крайней мере # 2.

Пример кода

Здесь - ручка с кодом ниже, который иллюстрирует обе проблемы.

const router = new VueRouter({
  routes: [
    {
      path: "/",
      component: {
        template: '<p>Homepage template</p>'
      }
    },
    {
      path: "/subpage",
      component: {
        template: '<p>Subpage template</p>'
      }
    }
  ]
});

// Globally registered BaseLink.
Vue.component('BaseLinkGlobal', {
  props: {
    href: String
  },
  template: `
    <a
      :href="href"
      class="BaseLinkGlobal"
    >
      <slot />
    </a>
  `
})

const vue = new Vue({
  el: "#app",
  router,
  components: {
    // Locally registered BaseLink.
    BaseLinkLocal: {
      props: {
        href: String
      },
      template: `
        <a
          :href="href"
          class="BaseLinkLocal"
        >
          <slot />
        </a>
      `
    }
  },
  template: `
    <div>
      <!-- 2 router links. One uses locally registered BaseLink
        -- and the other one a globally registered one. -->
      <nav>
        <router-link
          to="/"
          tag="base-link-local"
        >
          Home
        </router-link>
        <router-link
          to="/subpage"
          tag="base-link-global"
        >
          Subpage
        </router-link>
      </nav>
      <router-view />
    </div>
  `
});

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Это для решения проблемы # 2

Глобальный компонент не наследует прослушиватель событий соединения маршрутизатора.Вы можете сделать его наследующим, добавив v-on="$listeners" к глобальному компоненту.

// Globally registered BaseLink.
Vue.component('BaseLinkGlobal', {
  props: {
    href: String
  },
  template: `
    <a
      :href="href"
      class="BaseLinkGlobal"
      v-on="$listeners"
    >
      <slot />
    </a>
  `
})

Ссылка работает после ее добавления: https://codepen.io/jacobgoh101/pen/YvqJxL?editors=0010

0 голосов
/ 05 июня 2018

Вы можете создать базовый компонент ссылки, который может удваиваться как обычный тег a или <router-link>, когда вы хотите.

//Base link

<template>
  <component :is="type" :class="{'base': type === 'a'}" v-bind="$attrs">
    <slot></slot>
  </component>
</template>

<script>
export default {
  props: {
    routerLink: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    type() {
      return this.routerLink ? 'router-link' : 'a'
    }
  }
}
</script>

<style scopex>
.base {
  border: 1px solid red;
}
</style>

Использование

, когда вы хотите использовать егокак обычная ссылка, просто не предоставляйте реквизит router-link, как показано ниже:

<base-link>This is a base a tag</base-link>

Чтобы использовать его в качестве router-link, просто добавьте реквизит router-link вместе с реквизитом to:

<base-link router-link to="/">This is router-link</base-link>

Объяснение о компоненте base-link:

  • Мы используем component, который предоставляется vuejs для визуализации тега a или router-link основано на истинности routerLink реквизита.
  • Класс .base добавляется, если это нормальная ссылка, т.е. a
  • мы связываем $attrs, что позволяет нам сделать компонент более прозрачным, т. Е. Позволяет использовать такие атрибуты, как href или to, не передавая их в качестве реквизита.

    <base-link href="https://google.com">go to google</base-link>
    

Вы можете посмотреть здесь для получения дополнительной информации об использовании $attrs

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...