0

Code


export default class Random extends Vue {
  // data
  public nowIndex: number = -1;
  public swiperOption: Object = {
    slidesPerView: 6,
    slidesPerGroup: 6,
    loopFillGroupWithBlank: true,
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev"
    },
    on: {
      click: function(this: any): void {
        nowIndex = this.clickedSlide.dataset.key;
      }
    }
  };
}

Question: Click event's this direct to the Swiper element , I need it to get a key to tell me which one is being clicked , and I want save this key in vue data ---- nowIndex , but I had a error says "Cannot find name 'nowIndex'"

What I do: I try defined a public value vue direct to this in the class , but it does not work , the error also says "Cannot find name 'vue'"

End: I hope someone can see this and give me a way out , think you very much TAT .

luohe
  • 15
  • 6

1 Answers1

0

nowIndex = is a mistake because there's no nowIndex variable, and nowIndex class property should always be referred as this.nowIndex.

The documentation states:

Please note, that this keyword within event handler always points to Swiper instance

As this answer explains, this is design problem in a library that relies on this in callbacks; a function cannot use component this and swiper this contexts at the same time. This can be solved either by using self = this hack, or by binding function signature to one of these contexts and making it accept another one as a parameter.

This can be done with helper function as suggested in this answer:

function contextWrapper(fn) {
    const self = this;

    return function (...args) {
        return fn.call(self, this, ...args);
    }
}

export default class Random extends Vue {
  nowIndex: number = -1;
  swiperOption?: any;

  created() {
    this.swiperOption = { /*...*/
      on: {
        click: contextWrapper((swiperInstance: any) => {
          this.nowIndex = swiperInstance.clickedSlide.dataset.key;
        })
      }
    };
  }
}

Or by using a hack, in this case this semantics goes wrong:

export default class Random extends Vue {
  nowIndex: number = -1;
  swiperOption?: any;

  created() {
    const self = this;

    this.swiperOption = { /*...*/
      on: {
        click(this: any) {
          self.nowIndex = this.clickedSlide.dataset.key;
        })
      }
    };
  }
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • Thank you very much for resolve my question . I once try the first solution `self = this` in class like `public vue = this` , but it does not work , could you please teach me where and how can this code work ? – luohe Oct 29 '19 at 08:06
  • Will using the suger syntax , I almost forget the `constructor` , this is a big mistake , thanks again :) – luohe Oct 30 '19 at 01:23
  • Sorry to bother you , I find another question while I'm coding , the `this` in `bindAndPassContext` function bind , is direct to class `Random` not `VueComponent` , so if I update data , view not update , and I can't find a way to put `VueComponent this` in this function – luohe Oct 30 '19 at 08:11
  • You didn't specify how exactly you do class inheritance, but I guess this will be so with https://github.com/vuejs/vue-class-component . The problem with Vue classes is that they aren't really OOP, they are just a syntax for component definition. So my previous comment regarding `constructor` isn't relevant. You need to do this in `created` instead, that's where `self = this` will happen. I updated the post. – Estus Flask Oct 30 '19 at 10:05
  • So sorry for this vague question , the answer is perfect resolve my issue , but the relation between `VueComponent` and `Random` still confuse me , is the `@Component` decorator do some work between them ? – luohe Oct 31 '19 at 01:58
  • `@Component` class is syntactic sugar for `Vue.extend`, you can check sources. It gets all methods and properties you defined on Random to form a component. Vue component instance isn't an instance of Random. – Estus Flask Oct 31 '19 at 07:22