Vue-router: Expose RouterLink and RouterView components

Created on 9 Jan 2018  Â·  12Comments  Â·  Source: vuejs/vue-router

Most helpful comment

It would be so much better if we could avoid Router injecting global router-link component and instead import it explicitly whenever it is needed with import Link from 'vue-router/link'.

That way we will have self-contained components. Right now they are relying on obscure globally injected component, which you need to re-added during tests by using whole router instance, instead of declaring it imports at first place — in the component itself.

All 12 comments

Why not use Vue.component to attach them?

const RouterView = Vue.component('router-view');
const RouterLink = Vue.component('router-link');

@JounQin I didn't know you could use Vue component like that.

The problem is you need Vue Router installed on the Vue instance, which adds $route and $router as read-only values. So instead, you'd have to do something like this:

const localVue = createLocalVue()
localVue.use(VueRouter)
const RouterLink = localVue.component('router-link');

const wrapper = shallow(Comp, { localVue })
wrapper.find(RouterLink).props().to

Which I suppose isn't too bad 🤔

@eddyerburgh I "not too bad" good enough to close this? :-P

I think we still need the change for two reasons:

1) If you install Vue Router you can't mock $route or $router in a test, so you wouldn't be able to test a RouterLink component and mock the param value of $route.
2) We'd need to make users aware that they need to follow this pattern (installing VueRouter then calling Vue.component to access to RouterLink component). If we expose RouterLink and RouterView, users will be able to follow the recommended pattern for finding stubbed components

Looks good to me and it's very easy to add. What do you think? @yyx990803

I think that's good to have. Open to PR.

This would be a breaking change for the common js or browser build.

We can export them in vue-test-utils instead

It would be so much better if we could avoid Router injecting global router-link component and instead import it explicitly whenever it is needed with import Link from 'vue-router/link'.

That way we will have self-contained components. Right now they are relying on obscure globally injected component, which you need to re-added during tests by using whole router instance, instead of declaring it imports at first place — in the component itself.

I suppose this is rejected and we should follow https://github.com/vuejs/vue-router/issues/1976#issuecomment-356203955?

@ArmorDarks made a good case for this. I also just ran into this issue. Our component library, using its own set of node_modules, uses a different Vue instance which doesn't have the component. Being able to explicitly import it would solve this issue.

This seems like a simple non-breaking change.

@eddyerburgh @yyx990803

Here's a tentative PR: #2853

As mentioned by @eddyerburgh, we can't add additional exports to the umd/browser builds because they only support a single default export. We can however add them to the ES module builds without breaking backwards compatibility. I assume anyone interested in this feature is using ES modules anyway. I concede that it is a bit hacky though.

Finally, I am also convinced that this is not needed in vue-router. Here's the summary:

  • You can use Vue.component to get a reference to the components:
const RouterView = Vue.component('router-view');
const RouterLink = Vue.component('router-link');

Case closed, as far as I can tell.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alexstanbury picture alexstanbury  Â·  3Comments

baijunjie picture baijunjie  Â·  3Comments

druppy picture druppy  Â·  3Comments

saman picture saman  Â·  3Comments

posva picture posva  Â·  3Comments