Reputation: 53
Using vue v2.5.9 and vue-router v.3.0.1.
Minimal reproduction link: https://codepen.io/clarewhatever/pen/eyzMNo
I am trying to dynamically insert a <router-link>
element into component using the Vue.extend()
method.
Vue.component('markdown', {
name: 'markdown',
props: {
routeName: {
type: String,
required: true
},
routeLabel: {
type: String,
required: true
}
},
template: `<span ref="content"></span>`,
mounted () {
let self = this;
let routerLink = `<router-link :to="{ name: ${routeName} }">${routeLabel}</router-link>`;
let MarkdownContent = Vue.extend({
template: `<div>${routerLink}</div>`,
// router: self.$router,
mounted () {
// this.$router is undefined unless router is explicitly defined
console.log(this.$router);
}
});
new MarkdownContent().$mount(this.$refs.content);
}
});
The problem I'm running into is that this.$router
is undefined within the extend()
method so the route being passed to the router-link does not exist. If I pass in the router from the parent component (router: self.$router
) the router-link element mounts as expected.
I tried swapping out Vue.extend()
for Vue.component()
but ran into the same issue. I think it must have something to do with the vm.$mount
method being called on a constructor, although I'm not sure why it works that way. All of the docs show it being used that way, but I haven't been able to find an example that includes vue-router.
Upvotes: 0
Views: 3322
Reputation: 55664
By creating a new Vue instance and mounting it, via new MarkdownContent().$mount(...)
, you are breaking the normal paradigm of parent/child relationship. The VueRouter plugin automatically sets the reference for this.$router
for child components included in the template. But, by manually mounting the component, you lose that reference.
Instantiating and mounting a new component just to render a <router-link>
tag seems very roundabout. But, if you really need do it this way, you just need to specify the router
reference in the component definition object:
let MarkdownContent = Vue.extend({
router,
template: `<div>${routerLink}</div>`,
mounted () {
console.log(this.$router);
}
});
Upvotes: 3