Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/component-naming-conflicts.md
1---2title: Avoid Component Naming Conflicts Between Global and Local3impact: HIGH4impactDescription: Naming conflicts cause unexpected component rendering and hard-to-debug issues5type: gotcha6tags: [vue3, component-registration, naming-conflicts, global-local, debugging]7---89# Avoid Component Naming Conflicts Between Global and Local1011**Impact: HIGH** - When a global component and a local component have the same name (or resolve to the same name due to casing differences), unexpected behavior occurs. The precedence rules can be confusing, and the wrong component may render silently without any error. This is particularly problematic when using third-party component libraries.1213## Task Checklist1415- [ ] Use unique, prefixed names for global components (e.g., `BaseButton`, `AppHeader`)16- [ ] Check for naming conflicts when adding global components17- [ ] Explicitly alias local components if there's potential conflict18- [ ] When overriding third-party components, document and test thoroughly1920**Incorrect:**21```javascript22// main.js23import { createApp } from 'vue'24import Button from './components/Button.vue'2526const app = createApp(App)27app.component('Button', Button) // Global Button28```2930```vue31<!-- SomeComponent.vue -->32<script setup>33// This local Button might conflict with global Button34import Button from './local/Button.vue'35</script>3637<template>38<!-- Which Button renders? Behavior may be unexpected -->39<Button>Click me</Button>40</template>41```4243```vue44<!-- Another confusing scenario -->45<script setup>46// Registering with camelCase47import MyButton from './MyButton.vue'48</script>4950<template>51<!-- Using kebab-case - might match a global 'my-button' instead -->52<my-button>Click</my-button>53</template>54```5556**Correct:**57```javascript58// main.js - use prefixes for global components59import { createApp } from 'vue'60import BaseButton from './components/BaseButton.vue'61import BaseIcon from './components/BaseIcon.vue'6263const app = createApp(App)64app.component('BaseButton', BaseButton)65app.component('BaseIcon', BaseIcon)66```6768```vue69<!-- SomeComponent.vue -->70<script setup>71// Local components have distinct names72import SubmitButton from './local/SubmitButton.vue'73</script>7475<template>76<!-- No ambiguity - each name is unique -->77<BaseButton>Generic button</BaseButton>78<SubmitButton>Submit form</SubmitButton>79</template>80```8182## Explicit Aliasing for Clarity8384When you intentionally want to override or have similar names, use explicit aliasing:8586```vue87<script setup>88// Explicit alias to avoid confusion89import { default as LocalButton } from './Button.vue'90</script>9192<template>93<LocalButton>Local version</LocalButton>94</template>95```9697```vue98<!-- Options API with explicit component name -->99<script>100import ThirdPartyModal from 'some-library'101import CustomModal from './CustomModal.vue'102103export default {104components: {105// Explicit names prevent ambiguity106LibraryModal: ThirdPartyModal,107CustomModal108}109}110</script>111```112113## Resolution Order114115Understanding Vue's component resolution order helps debug issues:1161171. **Local registration** takes precedence over global1182. **Exact case match** takes precedence over case-insensitive match1193. Self-referencing component name (file name) has lowest priority120121```vue122<!-- If all exist: GlobalButton, local Button, and file is Button.vue -->123<script setup>124import Button from './Button.vue' // Local registration125</script>126127<template>128<!-- Resolves to locally imported Button, not global -->129<Button />130</template>131```132133## Third-Party Library Conflicts134135```vue136<script setup>137// Be explicit when using components from multiple libraries138import { Button as AntButton } from 'ant-design-vue'139import { Button as ElButton } from 'element-plus'140</script>141142<template>143<AntButton>Ant Design</AntButton>144<ElButton>Element Plus</ElButton>145</template>146```147148## Naming Convention Strategy149150| Component Type | Naming Pattern | Example |151|----------------|---------------|---------|152| Base/Global | `Base*` or `App*` prefix | `BaseButton`, `AppHeader` |153| Domain-specific | Domain prefix | `UserCard`, `ProductList` |154| Page components | `*Page` or `*View` suffix | `HomePage`, `UserView` |155| Layout components | `*Layout` suffix | `DefaultLayout`, `AdminLayout` |156157## Reference158- [Vue.js Component Registration](https://vuejs.org/guide/components/registration.html)159- [GitHub Issue: Global component naming conflicts](https://github.com/vuejs/vue/issues/4434)160