Skip to content

Some rules are not working while using vue-class-component #1000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
horrylala opened this issue Dec 7, 2019 · 7 comments
Closed

Some rules are not working while using vue-class-component #1000

horrylala opened this issue Dec 7, 2019 · 7 comments

Comments

@horrylala
Copy link

My environment

  • ESLint version:6.7.1
  • eslint-plugin-vue version:6.0.1
  • Node version:v11.14.0

Please show your full configuration:

module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    // airbnb
    'airbnb-base',
    // vue lint
    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
    'plugin:vue/recommended',
    // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin
    'plugin:@typescript-eslint/recommended',
    // prettier
    'prettier',
    'prettier/@typescript-eslint',
    'prettier/vue',
    '@vue/typescript'
  ],
  plugins: [
    // 'html'
  ],
  rules: {
    // ... 
    'no-multiple-empty-lines': ["error", { "max": 1 }],
    // ===
    'eqeqeq': ["error", "always"],
    // max-len: 180
    'max-len': ['error', 180],
    // todo: vue/order-in-components, not working
    // todo: vue/prop-name-casing , not working,
    // todo: vue/no-async-in-computed-properties , not working
    // todo: vue/no-duplicate-attributes ,not working
    'vue/no-dupe-keys': ['error'], // still not working 
    /*--------------------- vue rules ---------------------*/
    // Vue component naming,PascalCase:'MyComponent ',kebab-case:'my-component'
    'vue/name-property-casing': ['error', 'PascalCase'],
    // vue template naming,PascalCase:<MyComponent></MyComponent>  kebab-case: '<my-component></my-component>'
		'vue/component-name-in-template-casing': ['error', 'kebab-case'],
    /*--------------------- ts rules ---------------------*/
		'@typescript-eslint/no-unused-vars': ['error'],
    // typescript-eslint
    '@typescript-eslint/interface-name-prefix': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    'parser': '@typescript-eslint/parser',
    'project': 'tsconfig.json',
    'tsconfigRootDir': './',
    'extraFileExtensions': ['.vue']
  },
};

What did you do?

import { Vue } from "vue-property-decorator"

interface IState {
  arr: []
}
interface IProps {
  'prop-a': number
}

export default class Home extends Vue<IState, IProps> {
  // todo:eslint message: string = 'hello'
  message = 'hello'

  activated () {
    this.$el = 'nnn'
    console.log('actived')
  }

  onClick (): void {
    const message = 'dd'
    console.log(message)
    console.log(this.message)
    const longStr = 'str1234567…………189190191……str1………189190191……189190191……str1234567…………18919019str1234567…………189190191……str1234567…………189190191……str1234567…………189190191……1……'
    console.log(longStr)
  }

  get valA () {
    return Promise.all([new Promise((resolve) => {resolve('hhh')})])
  }
}

What did you expect to happen?
It should show some errors.

What actually happened?

Nothing errors are shown.

More description
I just import vue and typescript without using vue-cli. And i want using eslint-plugin-vue to lint my vue files which using vue-class-component.

@frck006
Copy link

frck006 commented Dec 22, 2019

I have the same problem.

When I use a classic mono file vue.js without "vue-property-decorator", it works:
image

But with "vue-property-decorator", it doesn't work.
The linter says nothing:
image

Regards.

@ota-meshi
Copy link
Member

Thank you for this issue.

Currently, this plugin does not support vue-class-component.

In order for this plugin to support vue-class-component, it is necessary to first identify the issues with each rule.

I want you to help with this task.

@armano2
Copy link
Contributor

armano2 commented Jan 3, 2020

@ota-meshi class-component and property-decorator is not only used for typescript (but mostly).

Main issue is with helper functions, there is no support for classes in them, getComponentProps is good example of function like this.
https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/utils/index.js#L430


in case of typescript + class some of rules are useless or they can be replaced by enforcing additional syntax on typescript, eg. if @Prop decorator is used we should require readonly property.
this eliminates need for rules that checks if prop value is mutated, this is validated by typescript if prop is readonly.


examples of rules that should be used in typescript + class:

require-readonly-prop

module.exports = {
  meta: {
    fixable: 'code'
  },
  create (context) {
    function checkClassProperty (node) {
      const parent = node.parent
      if (parent.type === 'ClassProperty') {
        if (!parent.readonly) {
          context.report({
            message: '@Prop decorator should be readonly',
            node: parent.key,
            fix (fixer) {
              return fixer.insertTextBefore(parent.key, 'readonly ')
            }
          })
        }
      } else {
        context.report({
          message: '@Prop decorator can be present only on ClassProperty',
          node
        })
      }
    }

    return {
      "Decorator[expression.type='Identifier'][expression.name='Prop']" (node) {
        checkClassProperty(node)
      },
      "Decorator[expression.type='CallExpression'][expression.callee.type='Identifier'][expression.callee.name='Prop']" (node) {
        checkClassProperty(node)
      }
    }
  }
}

no-undefined-data

module.exports = {
  meta: {
    fixable: undefined,
    messages: {
      error: 'Component data must have value, otherwise it\'s not going to be reactive'
    }
  },
  create (context) {
    function isUndefined (node) {
      if (!node) {
        return true
      }
      return node.type === 'Identifier' && node.name === 'undefined'
    }

    function hasComponentDecorator (node) {
      if (!node || !node.decorators || !node.decorators.length) {
        return false
      }
      return node.decorators.some((el) => {
        return (
          el.type === 'Decorator' &&
          el.expression &&
          (
            (
              el.expression.type === 'Identifier' &&
              el.expression.name === 'Component'
            ) || (
              el.expression.type === 'CallExpression' &&
              el.expression.callee &&
              el.expression.callee.type === 'Identifier' &&
              el.expression.callee.name === 'Component'
            )
          )
        )
      })
    }

    return {
      'ClassDeclaration > ClassBody > ClassProperty' (node) {
        if (
          (!node.decorators || !node.decorators.length) &&
          hasComponentDecorator(node.parent.parent) &&
          isUndefined(node.value)
        ) {
          context.report({
            messageId: 'error',
            node
          })
        }
      }
    }
  }
}

note: this is just example and they may not support all cases (they require @Component decorator to be present on class level)

@goldingdamien
Copy link

@ota-meshi "Currently, this plugin does not support vue-class-component." - Can you provide more information please?
I do not know how this library performs the checks.
Which rules(or in general) do not work for vue-class-component and why?
I might look into helping fix this, but I am not sure where to start.

@lgarczyn
Copy link

lgarczyn commented Mar 23, 2021

Another rule doesn't work: match-component-file-name

Doc: https://github.com/vuejs/eslint-plugin-vue/blob/master/docs/rules/match-component-file-name.md
Issue: #667

<script lang="ts">
// components/Normal.vue
import { Component, Vue } from 'vue-property-decorator';

// @vue/component
@Component
export default class Lol extends Vue {
    render(): null { return null; }
}
</script>

with the rule declared as

{
    'vue/match-component-file-name': ['error', {
      extensions: ['.vue', 'vue', 'vue.ts', 'jsx'],
      shouldMatchCase: true,
    }]
}

@lgarczyn
Copy link

This is still an issue, are there plans to fix it?

@FloEdelmann
Copy link
Member

Vue Class Component is no longer actively maintained and not recommended for Vue 3: https://class-component.vuejs.org/

This library is no longer actively maintained. It is no longer recommend to use Class-based components in Vue 3. The recommended way to use Vue 3 in large applications is Single-File Components, Composition API, and <script setup>.

So I suggest to not invest time in eslint-plugin-vue to start supporting this.

@FloEdelmann FloEdelmann closed this as not planned Won't fix, can't repro, duplicate, stale Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants