vuejs/eslint-plugin-vue

`'vue/no-unused-refs': 'error'` should work as expected

Closed this issue · 2 comments

Checklist

  • I have tried restarting my IDE and the issue persists.
  • I have read the FAQ and my problem is not listed.

Tell us about your environment

  • ESLint version: 8.57.0
  • eslint-plugin-vue version: 9.24.0
  • Vue version: 3.4.27
  • Node version: v22.12.0
  • Operating System: macOS 15.5 (24F74)

Please show your full configuration:

/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution');

module.exports = {
  root: true,
  env: {
    es2020: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    'plugin:vue/vue3-recommended',
    'plugin:vuetify/recommended',
    '@vue/eslint-config-typescript/recommended',
    '@vue/eslint-config-prettier',
    'airbnb-base',
    'plugin:json/recommended',
    'prettier',
    'plugin:storybook/recommended',
    'plugin:playwright/recommended',
    '.eslintrc-auto-import.json',
    'plugin:@intlify/vue-i18n/recommended-legacy',
    'plugin:tailwindcss/recommended',
  ],
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 'latest',
  },
  plugins: ['vue'],
  globals: { NodeJS: 'readonly' },
  settings: {
    'vue-i18n': {
      localeDir: './src/assets/language/*.json',
    },
    'import/resolver': {
      typescript: {
        project: './tsconfig.app.json',
      },
    },
  },
  rules: {
    'tailwindcss/no-custom-classname': 'off',
    'tailwindcss/classnames-order': 'off',
    '@intlify/vue-i18n/no-unused-keys': [
      'error',
      {
        extensions: ['.ts', '.vue'],
      },
    ],
    '@intlify/vue-i18n/key-format-style': [
      'error',
      'camelCase',
      {
        allowArray: false,
        splitByDots: false,
      },
    ],
    '@intlify/vue-i18n/no-missing-keys-in-other-locales': [
      'error',
      {
        ignoreLocales: [],
      },
    ],
    'playwright/expect-expect': [
      'error',
      {
        assertFunctionNames: [],
      },
    ],
    'playwright/prefer-strict-equal': 'error',
    'playwright/prefer-to-be': 'error',
    'playwright/prefer-to-have-count': 'error',
    'playwright/prefer-to-have-length': 'error',
    'playwright/prefer-hooks-in-order': 'error',
    'playwright/prefer-hooks-on-top': 'error',
    'playwright/prefer-equality-matcher': 'error',
    'playwright/prefer-comparison-matcher': 'error',
    'playwright/prefer-lowercase-title': 'error',
    'playwright/prefer-web-first-assertions': 'error',
    'playwright/prefer-locator': 'error',
    'playwright/prefer-native-locators': 'error',
    'vue/require-explicit-emits': 'off',
    'vue/no-useless-v-bind': 'error',
    'vue/no-required-prop-with-default': 'error',
    'vue/no-unused-refs': 'error',
    'import/extensions': 'off',
    'import/consistent-type-specifier-style': 'error',
    'import/order': [
      'error',
      {
        groups: ['type', 'external'],
        'newlines-between': 'always',
      },
    ],
    'func-call-spacing': 'off',
    'no-bitwise': [
      'error',
      {
        allow: ['|'],
      },
    ],
    'no-console': [
      'error',
      {
        allow: ['warn', 'error'],
      },
    ],
    'import/no-extraneous-dependencies': [
      'error',
      {
        devDependencies: true,
      },
    ],
    'no-await-in-loop': 'off',
    'no-restricted-syntax': [
      'error',
      {
        selector: 'ForInStatement',
        message:
          'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
      },
      {
        selector: 'LabeledStatement',
        message:
          'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
      },
      {
        selector: 'WithStatement',
        message:
          '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
      },
    ],
  },
};

What did you do?

❌ CASE 1: was not detected

The rule at https://eslint.vuejs.org/rules/no-unused-refs.html#rule-details mentions checking inside , but I think this case should also be reported as an error. What do you think?

<WeiConverterInput
  ref="weiConverterInput"
  ...

<script lang="ts" setup>
const weiConverterInput = ref();

// weiConverterInput is never used

✅ CASE 2: successfully detected

<WeiConverterInput
  ref="weiConverterInput"
  ...

<script lang="ts" setup>
// const weiConverterInput = ref();

What did you expect to happen?

Both cases above should be an error

What actually happened?

CASE 2 only was okay

Repository to reproduce this issue

repoduction demo

The ref in the template is being used, so it's expected that this rule doesn't throw an error.

The weiConverterInput variable isn't being used in script, which should trigger a warning—but that's outside the scope of this rule.
You could try enabling ESLint's no-useless-assignment or other rules to catch it.

@waynzh Thank you for the quick reply and suggestion! I got what you mean. I tried no-useless-assignment and it does not seem working as expected but I will try other rules.