language-tools icon indicating copy to clipboard operation
language-tools copied to clipboard

[vue-component-meta] When the props name starts with 'on', it is not included in the generated meta props

Open Zephyrrro opened this issue 1 year ago • 4 comments

Vue - Official extension or vue-tsc version

2.2.0

VSCode version

1.96.4 (Universal)

Vue version

3.3.8

TypeScript version

5.0.2

System Info

System:
    OS: macOS 13.4
    CPU: (10) arm64 Apple M1 Pro
    Memory: 232.38 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node
    Yarn: 1.22.21 - ~/Library/pnpm/yarn
    npm: 8.19.2 - ~/.nvm/versions/node/v18.12.1/bin/npm
    pnpm: 7.18.2 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 132.0.6834.160
    Safari: 16.5

package.json dependencies

{
  "devDependencies": {
    "@vue/language-plugin-pug": "2.2.0",
    "vue": "3.3.8",
    "vue-component-meta": "2.2.0",
    "typescript": "5.0.2"
  }
}

Steps to reproduce

  1. create a SFC with the below contents.
<template lang="pug">
div
</template>

<script lang="ts" setup>
defineProps<{
  onFoo: () => void;
  bar: () => void;
}>();
</script>
  1. then use vue-component-meta to extract the meta-data.
import { createChecker } from 'vue-component-meta';

const componentPath = path.resolve(__dirname, '../src/test.vue');

const checker = createChecker(
  path.resolve(__dirname, '../tsconfig.json'),
  {
    forceUseTs: true,
    printer: { newLine: 1 },
    noDeclarations: true,
  },
);

const meta = checker.getComponentMeta(componentPath);
console.log(meta)

What is expected?

there is an item in meta-data's props like this

  {
    "name": "onFoo",
    "global": false,
    "description": "",
    "tags": [],
    "required": true,
    "type": "() => void",
    "declarations": [],
    "schema": {
      "kind": "event",
      "type": "(): void"
    }
}

What is actually happening?

Can not find onFoo in the generated meta-data's props

{
  "type": 1,
  "props": [
    {
      "name": "bar",
      "global": false,
      "description": "",
      "tags": [],
      "required": true,
      "type": "() => void",
      "declarations": [],
      "schema": {
        "kind": "event",
        "type": "(): void"
      }
    },
    // ... global props
  ],
  "events": [],
  "slots": [],
  "exposed": [
    {
      "name": "onFoo",
      "type": "() => void",
      "description": "",
      "declarations": [],
      "schema": {
        "kind": "event",
        "type": "(): void"
      }
    },
    {
      "name": "bar",
      "type": "() => void",
      "description": "",
      "declarations": [],
      "schema": {
        "kind": "event",
        "type": "(): void"
      }
    }
  ]
}

Link to minimal reproduction

No response

Any additional comments?

No response

Zephyrrro avatar Feb 06 '25 07:02 Zephyrrro

Not sure if this was intentional.

https://github.com/vuejs/language-tools/blob/10ca343d2d7b2cef7bfc4dc06656ee1eff4680e2/packages/component-meta/lib/base.ts#L318

KazariEX avatar Feb 06 '25 10:02 KazariEX

Not sure if this was intentional.

language-tools/packages/component-meta/lib/base.ts

Line 318 in 10ca343

.filter(prop => !propEventRegex.test(prop.name));

It does seem to be the reason; is there a configuration to turn off this behavior? it feels a bit strange 🤔

Zephyrrro avatar Feb 06 '25 11:02 Zephyrrro

Looking at the Vue docs, filtering those props out is probably intentional because that is how you define event listeners for render functions: https://vuejs.org/guide/extras/render-function.html#v-on

absidue avatar Feb 06 '25 20:02 absidue

Looking at the Vue docs, filtering those props out is probably intentional because that is how you define event listeners for render functions: https://vuejs.org/guide/extras/render-function.html#v-on

I know this.

Playground In the playground, onFoo can be regarded as either props, passed in with v-bind, or events, passed in with v-on; so theoretically, onFoo should be regarded as at least one of props or events.

but in this case, onFoo does not appear in either, so I think the output is not as expected 🤔

Zephyrrro avatar Feb 07 '25 03:02 Zephyrrro

Fixed by https://github.com/vuejs/language-tools/pull/5369.

KazariEX avatar Jul 07 '25 14:07 KazariEX