Les composants partagés sont des éléments d'interface utilisateur réutilisables à travers l'application. Ils sont conçus pour être indépendants et configurables via des props.
Composant d'autocomplétion d'adresse qui s'intègre avec une API de géocodage.
| Nom | Type | Requis | Défaut | Description |
|---|---|---|---|---|
| modelValue | AddressItem | Non | undefined | Adresse sélectionnée |
| searchTerm | string | Non | '' | Terme de recherche actuel |
| Nom | Paramètres | Description |
|---|---|---|
| update:modelValue | AddressItem | Émis lorsque l'utilisateur sélectionne une adresse |
| update:searchTerm | string | Émis lorsque l'utilisateur tape dans le champ de recherche |
interface AddressItem {
geometry: any[];
properties: {
city: string;
label: string;
postcode: string;
housenumber?: string;
};
}
<template>
<AddressAutocomplete
v-model="selectedAddress"
v-model:search-term="searchTerm"
/>
</template>
<script setup>
const selectedAddress = ref();
const searchTerm = ref('');
</script>
Composant d'affichage du résumé d'un contrat avec les informations du client et les détails du contrat.
| Nom | Type | Requis | Défaut | Description |
|---|---|---|---|---|
| request | Request | Oui | - | Objet contenant les informations de la demande |
interface Contact {
name?: string;
lastname?: string;
email?: string;
street?: string;
postalCode?: string;
city?: string;
isPro?: boolean;
}
interface Price {
ht?: number;
ttc?: number;
}
interface Offer {
price?: Price;
maintenanceOffer?: {
name?: string;
};
}
interface Request {
contact?: Contact;
offer?: Offer;
equipments?: Array<any>;
}
<template>
<ContractSummaryCard :request="request" class="mb-8" />
</template>
<script setup>
const { data: request } = await useFetch(`/api/requests/${reqID}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
</script>
Composant de navigation entre les étapes d'un formulaire ou d'un processus.
| Nom | Type | Requis | Défaut | Description |
|---|---|---|---|---|
| steps | Array<{ id: string; label: string }> | Oui | [] | Liste des étapes |
| currentStep | string | Oui | - | ID de l'étape courante |
| canContinue | boolean | Non | true | Si false, désactive le bouton suivant |
| Nom | Paramètres | Description |
|---|---|---|
| next | - | Émis lorsque l'utilisateur clique sur Suivant |
| prev | - | Émis lorsque l'utilisateur clique sur Précédent |
| goto | stepId: string | Émis lorsque l'utilisateur clique sur une étape spécifique |
<template>
<StepNavigation
:steps="steps"
:current-step="currentStep"
:can-continue="canContinue"
@next="goToNextStep"
@prev="goToPrevStep"
@goto="goToStep"
/>
</template>
<script setup>
const steps = [
{ id: 'info', label: 'Informations' },
{ id: 'address', label: 'Adresse' },
{ id: 'summary', label: 'Récapitulatif' },
];
const currentStep = ref('info');
function goToNextStep() {
// Logique pour passer à l'étape suivante
}
function goToPrevStep() {
// Logique pour revenir à l'étape précédente
}
function goToStep(stepId) {
// Logique pour aller à une étape spécifique
}
</script>
kebab-caseLes composants utilisent les variables CSS définies dans le thème Nuxt UI. Pour personnaliser :
/* assets/css/main.css */
:root {
--primary: #3498db;
--primary-dark: #2980b9;
--text: #2d3436;
/* ... autres variables */
}
Les textes des composants sont gérés via le système de traduction Nuxt i18n. Pour ajouter une nouvelle langue :
// locales/fr.json
{
"addressAutocomplete": {
"placeholder": "Entrez votre adresse",
"noResults": "Aucun résultat, essayez une autre adresse"
}
}
Chaque composant doit être accompagné de tests unitaires. Exemple avec Vitest :
// tests/components/shared/AddressAutocomplete.spec.ts
import { mount } from '@vue/test-utils';
import { describe, it, expect } from 'vitest';
import AddressAutocomplete from '~/components/shared/AddressAutocomplete.vue';
describe('AddressAutocomplete', () => {
it('affiche le placeholder par défaut', () => {
const wrapper = mount(AddressAutocomplete);
expect(wrapper.find('input').attributes('placeholder')).toContain('Entrez votre adresse');
});
});
@nuxt/ui : Composants UI de basevue : Framework principal@vueuse/core : Utilitaires de compositionapp.vue<template>
<div class="address-form">
<h2>Adresse de livraison</h2>
<AddressAutocomplete
v-model="selectedAddress"
v-model:search-term="searchTerm"
class="mb-4"
/>
<UButton
:disabled="!selectedAddress"
@click="handleAddressSelect"
>
Valider l'adresse
</UButton>
</div>
</template>
<script setup lang="ts">
const selectedAddress = ref();
const searchTerm = ref('');
function handleAddressSelect() {
if (selectedAddress.value) {
// Traitement de l'adresse sélectionnée
console.log('Adresse sélectionnée :', selectedAddress.value);
}
}
</script>
<style scoped>
.address-form {
max-width: 500px;
margin: 0 auto;
padding: 1rem;
}
</style>