26

My vue component like this :

<template>
  <ul class="nav nav-tabs nav-tabs-bg">
    <li v-for="tab in tabs" role="presentation" :class="setActive(tab.url)">
      <a :href="baseUrl + tab.url">{{tab.title}}</a>
    </li>
  </ul>      
</template>
    
<script>
  export default {
    props: ['shop'],
    data() {
      return{
        tabs: [
          {
            title: 'product',
            url: '/store/' + this.shop.id + '/' + strSlug(this.shop.name)
          },
          {
            title: 'info',
            url: '/store/' + this.shop.id + '/' + strSlug(this.shop.name) + '/info'
          }
        ]
      }
    },
    methods: {
      setActive(pathname){
        return {active: window.location.pathname == pathname}
      },
      strSlug: function(val) {
        return _.kebabCase(val)
      }
    }
  }
</script>

If the code run, there exist error like this :

[Vue warn]: Error in data(): "ReferenceError: strSlug is not defined"

If I console.log(window.location.pathname), the result like this :

/store/21/chelsea-hazard-store

So if it is the same as url with data in tabs, then it will active

I call the strSlug method to convert each into lowercase and convert spaces into -

Seems it can not call the method from the data

How can I solve the error?

Asef Hossini
  • 655
  • 8
  • 11
samuel toh
  • 6,836
  • 21
  • 71
  • 108

3 Answers3

26

If you have a function in data that will be used in a context of another object (like an event handler, for example), then this will not point to the Vue instance. You will have to preserve the reference in another variable from the scope of data():

methods: {
    shuffle() {}
},
data() {
    var self = this;
    return {
        onClick: function() {
            self.shuffle()
        }
    }
}
gvlasov
  • 18,638
  • 21
  • 74
  • 110
  • 3
    I was looking for this to implement i18n (translation) in vuetify validation. It worked like a charm. I was driving me crazy. Thank You! .... based on your example i did self.$t('message') and it worked. – user4504661 Feb 11 '21 at 11:33
  • Vue calls data() once when creating data. After that, Vue manages the return value of data() with the $data property. Therefore, there is no need to replace this with self in data() since data() is never called from an event handler, etc. As The Guy with The Hat answered, just append this to strSlug. Similarly, there is no need to replace this with self in the definition of methods. – Jun1s Jan 23 '23 at 00:09
16

When accessing data or methods from within the vue object, use this.thing. In your case, that would be this.strSlug(this.shop.name).

The Guy with The Hat
  • 10,836
  • 8
  • 57
  • 75
11

Does not work even with 'this.' because that function has not been defined at the time data is being initialized. I think you have to do it in the created() life-cycle hook.

Brobic Vripiat
  • 176
  • 2
  • 12