Enrique Chavez
Enrique Chavez

Reputation: 1429

Incorrect component scope inside a $route watch function on VueJs

all.

I'm working on an app where I need to load/change data according to the app route path.

To know when the url has been changed I've added a watch function to the $route and I want to call a function in the same component to load data, all works the only thing is the scope of this inside the watch function instead of referred to the VueComponent instance is returning another object.

Here is my simplified code to get an idea

component.vue

<template>
  <div id="lists">
    {{pageTitle}}
  </div>
</template>

<script>
  export default {
    name: 'lists',
    data() {
      return {
        pageTitle: 'Some Title',
      };
    },
    created() {
      console.log('LOAD THE ASKED PATH');
      console.log(this.$route.params); /* Object */
      console.log(this); /* VueComponent Instance */
    },
    watch: {
      $route: (value) => {
        console.log('ROUTE CHANGED');
        console.log(value); /* Route Object */
        console.log(this); /* NOT A VueComponent */
        this.pageTitle = 'Some new title';
      },
    },
  };
</script>

This is the object I get for this inside the watch function

{default: {…}, __esModule: true}
default : beforeCreate : [ƒ]
beforeDestroy : [ƒ]
created : ƒ created()
data : ƒ data()
name : "lists"
render : ƒ ()
staticRenderFns : []
watch : {$route: ƒ}
_Ctor : {0: ƒ}
__file : "../my-app/src/components/Lists.vue"
__proto__ : Object

Not sure if this approach is correct or what I'm missing.

Any help will be appreciated.

Thanks in advance.

Upvotes: 1

Views: 246

Answers (1)

Bert
Bert

Reputation: 82469

Don't use arrow functions to define watch handlers (or methods, or computed values, or lifecycle methods, etc). Arrow functions bind this lexically, and they cannot be re-bound.

Instead, just use a regular function. Vue will bind it to the Vue.

watch:{
  $route: function(value){
    console.log('ROUTE CHANGED');
    console.log(value); /* Route Object */
    console.log(this); /* NOT A VueComponent */
    this.pageTitle = 'Some new title';
  }
},

Upvotes: 2

Related Questions