Home > Software design >  Methods and data value doesn't access to keydown listener Vue js
Methods and data value doesn't access to keydown listener Vue js

Time:09-28

I have this code in my mounted function :

 mounted () {
    document.addEventListener('keydown', function (e) {
      switch (e.keyCode) {
        case 37 :
          alert(this.indexPictures)
          break
      }
    })
  }

My data value :

  data: function () {
    return {
      indexPictures: this.index,
    }
  },

My result : undefined

I don't know why but I can't get value in data function and this is the same problem, from methods access. My result : is not a function

Do you have any ideas ?

CodePudding user response:

this inside data() function is not the same this as in computed, methods, watch, hook functions, etc... It's not the component instance, but its context. There are advanced cases when you might want to use this inside a component's data function but they're low level (e.g: for plugin developers). For the regular developer, a good rule is to never use this inside the data function. Note the data function is run before adding reactivity to the component and at that point computed and methods have not yet been declared.

That being said, I don't see a reason to create a reactive data prop called indexPictures if you already have index defined. Just use index directly wherever you would want to use indexPictures.

The only valid case for creating an alias for a prop is when you want to use a prop with v-model in which case you use a computed getter/setter. In the getter you return the prop and in the setter you $emit() an event which updates the value in parent which, in turn, updates the prop value for the child. See this answer for details.


To conclude: regardless of your reasons, if you want to alias index as indexPictures, use a computed:

  computed: {
    indexPictures() { return this.index }
  }

Now you can use this.indexPictures (or indexPictures in <template>) and it will always return the exact same value as this.index (or index).

Obviously, index has to be defined in the component.

CodePudding user response:

Not sure what this.index is but I will assume it is a prop or something similar.

Try removing the keyword function from the addEventListener.

 mounted () {
    document.addEventListener('keydown', (e)=> {
      switch (e.keyCode) {
        case 37 :
          alert(this.indexPictures)
          break
      }
    })
  }

It is not particularly relevant to the problem, but remove the function keyword from data as well:

data() {
    return {
      indexPictures: this.index,
    }
  },

The keyword function changes the scope, meaning this is bind to the function itself (in your case the callback). When you use an arrow function this keyword will be the same as in mounted - which means you can access your data.

From MDN docs:

Perhaps the greatest benefit of using Arrow functions is with methods like setTimeout() and EventTarget.prototype.addEventListener() that usually require some kind of closure, call, apply or bind to ensure that the function is executed in the proper scope.

Keep in mind if this is a part of a component it is a good idea to remove that listener before destroying the component.

  • Related