如何使路由器链接与自定义链接组件一起工作?

时间:2018-06-05 11:45:47

标签: javascript vue.js vue-component vue-router

<base-link>组件

我有一个Vue组件<base-link>,每次我想要一个achor时都会使用它。它主要用于应用特定于链接的样式,因此整个页面上的所有链接看起来都相同,而不应用全局样式。

<router-link>使用<base-link>

使用<router-link>组件创建链接时,我无法应用这些样式(<base-link>样式作用域),除非<router-link>使用我的<base-link>组件创建锚元素

幸运的是<router-link>提供tag attribute,这似乎就是这样做的。不幸的是,我无法让它发挥作用。我有两个问题:

  1. 我的所有组件都在本地注册(我使用带有Webpack的ES6模块,并在每次需要时在本地导入组件)。 <router-link>并不知道<base-link>组件是什么,并且无法呈现它。有没有办法为<router-link>注入本地组件?

  2. 要解决问题#1,我认为全局声明<base-link>组件已经足够了。不幸的是,它仍然无法运作。这次<base-link>组件正确呈现,但仍无法正常运行 - 不会对点击事件做出反应。在我看来,问题是它的href属性根本没有设置。有没有办法让<router-link>正确设置? (不手动设置)

  3. 问题

    如何解决问题#1和#2?我怀疑#1可能不可能,但我希望至少#2是。

    代码示例

    Here是一支带有以下代码的笔,它说明了这两个问题。

    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 :(得分:2)

您可以创建一个基本链接组件,可以在需要时将其翻倍为普通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>

有关基本链接组件的说明:

  • 我们使用vuejs提供的component根据a道具的真实性呈现router-link标记或routerLink
  • 如果.base为普通链接,则会添加ahref
  • 我们绑定$attrs,它允许我们使组件更透明,即允许我们使用to<base-link href="https://google.com">go to google</base-link> 等属性而不将它们作为道具传递。

    $attrs

您可以查看一下here,了解有关 gmm_list <- lapply(1:(length(ALLX$DE)-24), function(i) { tmp <- ALLX[i:(i+23),] DE <- as.matrix(as.numeric(tmp$DE)) p <- nrow(DE) rmrf_local <- as.matrix(as.numeric(tmp$rmrf_local)) SMB_L <- as.matrix(as.numeric(tmp$SMB_L)) HML_L <- as.matrix(as.numeric(tmp$HML_L)) MOM_L <- as.matrix(as.numeric(tmp$MOM_L)) bond_L <- as.matrix(as.numeric(tmp$bond_L)) h <- cbind(rmrf_local,SMB_L,HML_L,MOM_L,bond_L) gmm(DE ~ rmrf_local+SMB_L+HML_L+bond_L, x=h) })

用法的更多说明

答案 1 :(得分:1)

这是为了解决问题#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