9

I have an Ionic Vue app which uses the slides component to modify a reactive property each time it transitions. The pertinent code is like this:

<script lang="ts">
import { IonPage, IonContent, IonSlides, IonSlide,} from '@ionic/vue'

export default {
  name: 'Splash',
  components: { IonPage, IonContent, IonSlides, IonSlide,},
  data() {
    return {
      contentClass: 'bg-gradient-1',
    }
  },
  setup() {
    const slideOpts = {
      autoplay: {
        delay: 4000,
      },
    }    
    return { slideOpts }
  },
  methods: {
    slideChange({ target }) {
      const vm = this
      target.getActiveIndex().then((i) => {
        vm.contentClass = 'bg-gradient-' + i
      })
    },
  },
}
</script>

This generates the following error:

Unexpected aliasing of 'this' to local variable @typescript-eslint/no-this-alias

The reason I'm using const vm = this is because once inside the getActiveIndex method, the scope of this changes and I can't modify the contentClass data property.

Rather than just blindly disabling the ESLint rule to allow this to be assigned to a constant I wondered if anyone was able to offer a better/proper solution?

Many thanks.

Dan
  • 5,836
  • 22
  • 86
  • 140
  • 1
    Are you sure that scope of this is changed? You are using arrow function which should bind to this from outer scope. I am curios because I can't see reason why it should change. – farincz Jan 25 '21 at 12:18
  • Yes, very sure. Replacing `vm.contentClass = 'bg-gradient-' + i` with `this.contentClass = 'bg-gradient-' + i` causes an error ("unexpected aliasing of this to local variable"). Probably because the `slideChange` method isn't an arrow function; but I don't think it can be? – Dan Jan 25 '21 at 12:22
  • @Dan That sounds backwards :) Using `this.contentClass` wouldn't be aliasing `this`; rather it's `vm.conentClass` (where `vm` = `this`) that would cause the linter error. Do you have a link to GitHub repo that reproduces the problem? – tony19 Jan 25 '21 at 12:37

3 Answers3

8

yes there is one solution. You can add the following object in your ESlint config file

{
  "@typescript-eslint/no-this-alias": [
    "error",
    {
      "allowDestructuring": true, // Allow `const { props, state } = this`; false by default
      "allowedNames": ["vm"] // Allow `const vm= this`; `[]` by default
    }
  ]
}

for more info also check on TSLint: no-this-assignment

Amaarockz
  • 4,348
  • 2
  • 9
  • 27
3

can solve also it by not using data and go all-in with setup approach

<script lang="ts">
import { IonPage, IonContent, IonSlides, IonSlide,} from '@ionic/vue'

export default {
  name: 'Splash',
  components: { IonPage, IonContent, IonSlides, IonSlide,},
  setup() {
    const contentClass = ref<any>('bg-gradient-1');
    const slideChange = ({ target }) => {
      target.getActiveIndex().then((i) => {
        contentClass.value = 'bg-gradient-' + i
      })
    },
    const slideOpts = {
      autoplay: {
        delay: 4000,
      },
    }    
    return { slideOpts, contentClass, slideChange }
  }
}
</script>
Aaron Saunders
  • 33,180
  • 5
  • 60
  • 80
0

In .eslintrc file on rules key add "@typescript-eslint/no-this-alias": 0, for example in my case:

"rules": {
        "@typescript-eslint/no-var-requires": 0,
        "@typescript-eslint/no-explicit-any": 0,
        "@typescript-eslint/no-this-alias": 0,
        "no-console": 1, // Means warning
        "prettier/prettier": 2 // Means error
    }
pedro.caicedo.dev
  • 2,269
  • 2
  • 16
  • 19