Vue-class-component: $router & $route Exception with @Component

Created on 16 Jan 2019  路  8Comments  路  Source: vuejs/vue-class-component

When using @component with Vue-Router plugin.

This.$router and This.$route has an exception like :
Exception: TypeError: Cannot read property '_router' of undefined at Home.get (webpack-internal:///./node_modules/vue-router/dist/vue-router.esm.js:553:52) at Home.invokeGetter (:2:14)

Without @component decorator, this.$router is well loaded, but the component works wired (Can not using router.push() and render the page).

So this could be an issue about loading vue-router with @component decorator?

need repro

Most helpful comment

@AcodeWang You should not write the test method as an arrow function, since arrow functions are bound to the parent context, this will not be the Vue instance as you鈥檇 expect. Fix it like this:

@Component
export default class Home extends Vue {
  test() {
    this.$router.push(
      {
        name: 'login',
      },
    );
  }
}

All 8 comments

Please provide a reproduction. We can't determine what's going on from your description

@Component
export default class Home extends Vue {
test = () => {
console.log(this);
}
}

result :
screenshot 2019-01-17 at 09 17 35

vue.runtime.esm.js?2b0e:1832 TypeError: Cannot read property '_router' of undefined
at Home.get (vue-router.esm.js?8c4f:552)
at Home._this.test (Home.vue?42b8:66)
at VueComponent.invoker (vue.runtime.esm.js?2b0e:2132)
at VueComponent.Vue.$emit (vue.runtime.esm.js?2b0e:2652)
at VueComponent.handleClick (element-ui.common.js?5c96:9801)
at invoker (vue.runtime.esm.js?2b0e:2132)
at HTMLButtonElement.fn._withTask.fn._withTask (vue.runtime.esm.js?2b0e:1917)
logError @ vue.runtime.esm.js?2b0e:1832
globalHandleError @ vue.runtime.esm.js?2b0e:1823
handleError @ vue.runtime.esm.js?2b0e:1812
Vue.$emit @ vue.runtime.esm.js?2b0e:2654
handleClick @ element-ui.common.js?5c96:9801
invoker @ vue.runtime.esm.js?2b0e:2132
fn._withTask.fn._withTask @ vue.runtime.esm.js?2b0e:1917

Well the error itself is not really suprising, $route and $router won't evaluate correctly before the component has been mounted as a child of an app with a router since there's no $parent yet.

https://github.com/vuejs/vue-router/blob/dev/src/install.js#L38-L40

The error only happens as you actually access the getter with the console log at a time that accessing it makes no sense.

Do you get this error when actually using these components?

If this should be improved, it should be done in vue-router, I don'T see how this is related to vue-class-component

@LinusBorg
Thank you for your reply,

About your question, yes, I actually got this error when using the components.

An alternative solution I am using is to import the vue-router and using it without access to this.$router.

Could you explain a little to me why without @Component decorator, the Vue prototype can correctly get this.$router? That's why I was thinking the error is from @Component Decorator.

Result without @Component :

screenshot 2019-01-17 at 10 45 40

I'll have to ask you again to provide an actual reproduction - code in a repository that I can run.

Right now i'm trying to guess what you are actually doing, and can't reproduce what you are experiencing.

@LinusBorg

Ok , I am trying to explaine it better.

The object is to use vue-router in Typescript with this.$router

Two solutions :

  1. with @Component decorator
@Component
export default class Home extends Vue {
  test = () => {
    this.$router.push(
      {
        name: 'login',
      },
    );
  }
}

Not working, the with the exception tracked as
vue.runtime.esm.js?2b0e:1832 TypeError: Cannot read property '_router' of undefined
at Home.get (vue-router.esm.js?8c4f:552)
at Home._this.test (Home.vue?42b8:66)
at VueComponent.invoker (vue.runtime.esm.js?2b0e:2132)
at VueComponent.Vue.$emit (vue.runtime.esm.js?2b0e:2652)
at VueComponent.handleClick (element-ui.common.js?5c96:9801)
at invoker (vue.runtime.esm.js?2b0e:2132)
at HTMLButtonElement.fn._withTask.fn._withTask (vue.runtime.esm.js?2b0e:1917)
logError @ vue.runtime.esm.js?2b0e:1832
globalHandleError @ vue.runtime.esm.js?2b0e:1823
handleError @ vue.runtime.esm.js?2b0e:1812
Vue.$emit @ vue.runtime.esm.js?2b0e:2654
handleClick @ element-ui.common.js?5c96:9801
invoker @ vue.runtime.esm.js?2b0e:2132
fn._withTask.fn._withTask @ vue.runtime.esm.js?2b0e:1917

  1. Without @Component decorator, It is working.
export default class Home extends Vue {
  test = () => {
    this.$router.push(
      {
        name: 'login',
      },
    );
  }
}

So my question is how @Component decorator affect the result of the getter of this.$router

@AcodeWang You should not write the test method as an arrow function, since arrow functions are bound to the parent context, this will not be the Vue instance as you鈥檇 expect. Fix it like this:

@Component
export default class Home extends Vue {
  test() {
    this.$router.push(
      {
        name: 'login',
      },
    );
  }
}

@zhiquan-yu
Thank you, it helps and that's correct.

I found another issue in binding data through arrow function. It's the same problem. So better not to use the arrow function in vue-class-component when it's not needed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

valorad picture valorad  路  4Comments

vishr picture vishr  路  3Comments

asolopovas picture asolopovas  路  4Comments

tonypee picture tonypee  路  5Comments

viT-1 picture viT-1  路  4Comments