Vue Component Development
Component File Structure
Components live under src/components/<component-name>/Index.vue. Use kebab-case for directory names.
src/components/
my-component/
Index.vue # Main component entry
components/ # Sub-components (optional)
SubPart.vue
SFC Section Order
<template>
<!-- template -->
</template>
<script setup lang="ts">
// script
</script>
<style lang="less" scoped>
/* styles */
</style>
Script Setup Order
Inside <script setup lang="ts">, follow this strict order:
- External imports (npm packages)
- Internal imports (path aliases, see import order below)
defineOptions({ name: 'ComponentName' })(if needed)definePropswith interface +withDefaultsdefineEmitswith type aliasdefineModel(if needed)defineSlots(if needed)- Composables (
useI18n,useRouter, etc.) - Refs and reactive state
- Computed properties
- Watchers
- Methods / functions
- Lifecycle hooks (
onMounted,onBeforeUnmount, etc.) defineExpose(if needed)
Props Pattern
interface Props {
title?: string;
count?: number;
disabled?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
title: '',
count: 0,
disabled: false,
});
Emits Pattern
type Emits = (e: 'change', value: string) => void;
const emit = defineEmits<Emits>();
Multiple events:
type Emits = {
(e: 'change', value: string): void;
(e: 'update', id: number): void;
};
Import Order
Enforced by ESLint. Follow this sequence:
- npm packages (
vue,lodash,tippy.js) @blueking/*@services/*@hooks@router@stores@common/*@components/*@views/*@utils@helper/*@types@locales/*@styles/*@images/*- Relative imports (parent first, then current directory)
Template Attribute Order
v-forv-if / v-else-if / v-else / v-showidref / keyv-slotv-model- Other
v-*directives - Static attributes / dynamic bindings
@eventlisteners
Style Conventions
- Use
lang="less"(orpostcssfor global utility components) - Add
scopedunless styles must leak intentionally - Class names: kebab-case, prefixed with
dbm-or component-specific prefix - Avoid
!important; use specificity or BEM nesting
Auto-imported APIs
The project auto-imports Vue APIs (ref, computed, watch, onMounted, etc.) — no need to import them explicitly.
Only import non-auto-imported items.
Checklist
Before finishing a component:
- Props use
interface+withDefaults - Emits use
typealias - No
anytypes — useunknownor concrete types - Import order follows project convention
- Template attributes follow prescribed order
- Styles use
lang="less"with scoped (unless intentional) - Comments in Chinese where needed
- Error handling for async operations (try-catch)
- Cleanup in
onBeforeUnmount(tippy, observers, timers, etc.)
Converted and distributed by TomeVault — claim your Tome and manage your conversions.