vue-component-navigatorVS Code navigation helpers for Vue 2 Options API projects and Vue 3
This extension focuses on static relationships that are easy to miss in Vue codebases. It complements the official Vue tooling instead of replacing it, so local component tag definitions are intentionally left to the Vue language extension to avoid duplicate results. Current documented feature set: 2.0 Runtime SplitVersion
Demos
|
| Area | Supported relationships | Vue 2 | Vue 3 |
|---|---|---|---|
| Editor actions | Definitions, references, hover, completion, and CodeLens where the indexed relationship supports them. | Supported | Supported for indexed static relationships |
| Component usage | Static component imports, async component imports, simple aliases, usage CodeLens, command-component API calls, and static .vue import usages. |
Supported, including Vue.extend / JSX command modules |
Supported for <script setup>, createApp / h / JSX command modules, and static dynamic component maps |
| Props | Template prop usage to child prop definitions, including fallthrough through $attrs wrappers. |
Supported | defineProps inline, named, imported, and generic named type members; internal prop usages; $attrs / useAttrs() / mergeProps() fallthrough; static object v-bind |
| Events / emits | Template listeners to component emit declarations and emit call sites. | this.$emit(...) and listener fallthrough through $listeners wrappers |
defineEmits inline object/array, call signatures, named/imported/generic type members, and emit calls |
| Models | Model usage to component model contracts. | Covered through event and prop relationships where statically visible | defineModel() and defineModel('name') to both model props and update:* events from v-model / v-model:name |
| Slots | Slot definitions to parent slot usages. | Legacy <slot name> and slot="..." relationships |
defineSlots inline, named, imported, and generic type members to #name / v-slot:name |
| Template refs | Ref method calls to child component methods. | this.$refs.name.method() with completion, hover, definitions, and references |
ref.value?.method(), non-null assertions, type assertions, TSX/h refs, and useTemplateRef<T>() |
| Exposed methods | Exposed public methods to parent ref calls. | Component methods exposed through $refs |
defineExpose local functions, object methods, async methods, function expressions, inline arrows, and composable forwarding |
| Composables | Return members to destructured consumer usages. | Not applicable | Static composable / hook return-member reverse references |
| Provide / inject | Static provider keys to consumers. | Static string keys | Static strings, static Symbol keys, and InjectionKey relationships |
| Mixins | Static imported mixin members from workspace files. | Supported for .js, .ts, and .vue files |
Not targeted |
| Event Bus | Static event-name navigation, completion, hover, and references. | Supported after a bus is found from configured entry files | Not targeted |
| Global components | Static global registrations to component usages. | Vue.component(...) |
Not targeted |
| Third-party component refs | Known library ref methods. | Element UI and Vant ref methods such as form validation and input focus | Not targeted |
| Type-aware navigation | Component contract members found through TypeScript declarations. | Limited to static Options API patterns | defineProps, defineEmits, defineModel, defineSlots, defineExpose, typed template refs, and imported type declarations |
| Path aliases | Workspace aliases read from the nearest jsconfig.json or tsconfig.json. |
Supported | Supported |
Vue 3 Static Prop Relationships
Vue 3 prop navigation links parent template prop usage to child defineProps declarations when the relationship can be proven statically.
Supported template forms include:
- Direct props such as
<Child :title="title" />and kebab/camel case variants. v-model/v-model:name, indexed as both model prop usage andupdate:*event usage.- Wrapper fallthrough through
<Child v-bind="$attrs" />. useAttrs()aliases passed withv-bind, including simplecomputed(() => ({ ...attrs }))wrappers.mergeProps($attrs, props)when each argument can be resolved statically.- Static object
v-bind, including object literals and objects wrapped inref,shallowRef,reactive,shallowReactive,readonly,markRaw, or simplecomputedarrow returns. - Top-level aliases to
defineProps()/withDefaults(defineProps(), ...). - Top-level rest bindings such as
const { title, ...forwardedProps } = props, including type annotations on the destructuring pattern. - Multiple declarators in one statement, such as
const ignored = {}, childProps = { title: 'ok' }.
The scanner only follows top-level bindings in the component script blocks. It does not evaluate runtime branches, imported object values, dynamic property names, or complex TypeScript type expansion.
Event Bus Entry
Event Bus names are detected from Vue prototype registrations in entry files.
Default entry files:
src/main.jssrc/index.jssrc/main.tssrc/index.ts
If your project uses different bootstrap files, set vueComponentNavigator.entry to a workspace-relative path, an alias path, or an array of paths. Configured entries support aliases from compilerOptions.baseUrl / compilerOptions.paths in jsconfig.json or tsconfig.json.
The scanner only checks the entry file and one layer of literal import, import(), or require() targets. It does not recursively crawl the whole project.
Event Bus usage is ignored until the bus name is found from these entry files. There is no built-in fallback for $bus.
Commands
| Command | Description |
|---|---|
Vue Component Navigator: Show Status |
Shows index status and whether the active file is indexed. |
Vue Component Navigator: Reindex Workspace |
Rebuilds the workspace index. Use it after large refactors or config changes. |
Command Components
Imperative component wrappers are linked to their final business call sites when the relationship can be proven statically. Detection is content-based; command files do not need to use a specific filename.
A command module must:
- Default-import a workspace
.vuecomponent. - Render that component through Vue 2 JSX or Vue 3 JSX,
h(), orcreateVNode(). - Default-export a command object, either inline or through a local variable.
Supported exported methods include object methods, async object methods, local handler references, function expressions, and arrow functions:
const Dialog = {
open() {},
async confirm() {},
alert: alertHandler,
close: () => {},
}
export default Dialog
Business calls such as Dialog.open() and Dialog.confirm() appear in the real component's usage CodeLens. The command script also shows a clickable Used by N usages CodeLens. Hovering an exported method shows only that method's usage count and call locations.
Only default imports followed by direct member calls are indexed. Calls to methods that are not present in the exported command object are ignored. Destructured calls, computed property calls, CommonJS imports, runtime-generated method names, and cross-Vue-version relationships are intentionally out of scope.
Configuration
| Setting | Description |
|---|---|
vueComponentNavigator.entry |
Event Bus registration entry file or files. Accepts a string or string array. |
Boundaries
- Vue 2 and Vue 3 workspaces are indexed by detected Vue major version; their feature sets are intentionally separated.
- Component relationships never cross Vue major versions. A Vue 2 package importing a Vue 3 component, or the reverse, produces no component, prop, event, slot, ref, or provide/inject relationship.
- Files outside the workspace are ignored.
- Dynamic component names, computed
provide/injectkeys, runtime-only event names, and dynamic Event Bus names are out of scope. - Route lazy component imports and
<router-view>slot components are route configuration relationships, not template parent-child component usages. - Runtime-only
<component :is="...">variables are ignored unless a static map can prove the candidate components. - Complex TypeScript expansion such as conditional, mapped, or intersection type evaluation is intentionally limited.
- Static object
v-bindsupport is intentionally conservative. When the value comes from runtime control flow, an imported object, or a function return that cannot be resolved locally, it is ignored. - Command-component analysis only follows statically visible default imports, exported object methods, and direct member calls such as
Dialog.open().
The parser is deliberately conservative. When a relationship cannot be proven statically, the extension avoids returning a misleading result.



