# Jak poprawnie zaimplementować przycisk „Wstecz” w Vue: przewodnik techniczny dla deweloperów
Implementacja przycisku „Wstecz” w aplikacjach na Vue.js często wydaje się trywialna, ale w praktyce prowadzi do poważnych problemów z nawigacją i historią przeglądarki. Wielu deweloperów błędnie używa router.push() zamiast metod przeznaczonych do poruszania się po istniejącym stosie historii. To tworzy duplikujące się wpisy, psuje zachowanie przeglądarkowego przycisku „Wstecz” i generuje nieskończone pętle przejść. W tym artykule — technicznie precyzyjny przewodnik po poprawnej implementacji przycisku „Wstecz” z uwzględnieniem edge cases i doświadczenia użytkownika.
Dlaczego router.push() — to nie „wstecz"
Metoda router.push() dodaje nowy wpis do historii przeglądarki. Służy do przejścia do przodu na nowy trasa, nawet jeśli ten trasa był już wcześniej odwiedzony. W przeciwieństwie do niej, router.back() i router.go(-1) nie tworzą nowych wpisów — po prostu przesuwają wskaźnik po już istniejącym stosie historii.
Gdy używasz router.push() dla przycisku „Wstecz”, w rzeczywistości symulujesz przejście do przodu, maskując je jako powrót. Prowadzi to do następującej sekwencji:
- Użytkownik: Strona główna → Lista produktów → Produkt A
- Kliknięcie twojego przycisku „Wstecz” z
router.push('/list') - Historia staje się: Strona główna → Lista produktów → Produkt A → Lista produktów (duplikat)
Teraz, jeśli użytkownik kliknie przycisk „Wstecz” w przeglądarce, wróci na stronę „Produkt A”, a nie na „Stronę główną". Przy ponownym kliknięciu twojego przycisku ponownie zadziała push, i cykl się powtórzy.
Podstawowe metody nawigacji w Vue Router
Vue Router udostępnia trzy kluczowe metody do zarządzania historią:
router.push(location)— dodaje nowy wpis do historii.router.replace(location)— zastępuje bieżący wpis bez dodawania nowego.router.back()/router.go(-1)— przesuwa się wstecz po istniejącej historii.
Dla przycisku „Wstecz” w interfejsie jedynym poprawnym wyborem są router.back() lub router.go(-1). W pełni odpowiadają one zachowaniu przeglądarkowego przycisku i nie naruszają spójności stosu.
Obsługa edge cases: gdy historii brak
W praktyce użytkownicy często trafiają na stronę bezpośrednio — przez zewnętrzną linkę, odświeżenie strony lub po zamknięciu karty. W takich sytuacjach stos historii może być pusty lub zawierać tylko jeden wpis. Wywołanie router.back() nie spowoduje błędu, ale nic się nie stanie, co pozostawi użytkownika w zawieszeniu.
Aby temu zapobiec, należy przewidzieć zapasowy trasa (fallbackRoute). Logika powinna sprawdzać możliwość powrotu i, w razie jej braku, przekierowywać na bezpieczny trasa — na przykład na stronę główną lub sekcję nadrzędną.
Uniwersalny komponent przycisku „Wstecz"
Poniżej — przykład komponentu gotowego do produkcji, z obsługą wszystkich niezbędnych scenariuszy:
<script setup lang="ts">
import { computed } from 'vue'
import { useRouter, useRoute, type RouteLocationRaw } from 'vue-router'
const props = defineProps<{
fallbackRoute?: RouteLocationRaw
beforeNavigate?: () => boolean | Promise<boolean>
beforeRouterPush?: () => void
}>()
const router = useRouter()
const route = useRoute()
const isSamePage = computed<boolean>(() => {
const fromRoute = router.options.history.state?.back
if (!fromRoute || typeof fromRoute !== 'string') return false
const currentPrefix = route.path.split('/')[1]
const fromPrefix = fromRoute.split('/')[1]
return currentPrefix === fromPrefix
})
const goBack = async () => {
if (props.beforeNavigate) {
const shouldProceed = await props.beforeNavigate()
if (!shouldProceed) return
}
if (props.beforeRouterPush) {
props.beforeRouterPush()
return
}
if (isSamePage.value) {
router.back()
} else if (props.fallbackRoute) {
void router.push(props.fallbackRoute)
} else {
void router.push({ name: 'home' })
}
}
</script>
<template>
<q-btn
icon="arrow_back"
@click="goBack"
aria-label="Onzad"
/>
</template>
Ten komponent rozwiązuje kilka zadań jednocześnie:
- Obsługuje potwierdzenie przed odejściem (np. zapisanie szkicu)
- Rozróżnia przejścia wewnętrzne i zewnętrzne po prefiksach URL
- Przewiduje zapasowy trasa
- Pozwala na pełne nadpisanie logiki w razie potrzeby
Co ważne
- Nie używaj
router.push()dla przycisku „Wstecz” — narusza to model historii przeglądarki. - Zawsze przewiduj zapasowe zachowanie na wypadek bezpośredniego wejścia.
- Sprawdzaj kontekst przejścia: powrót wewnątrz sekcji i powrót z zewnątrz wymagają innej logiki.
- Obsługuj anulowanie przejścia przez asynchroniczne haki — to kluczowe dla formularzy i edytorów.
- Synchronizuj zachowanie z natywnym przyciskiem przeglądarki — użytkownik nie powinien zauważyć różnicy.
— Editorial Team
Brak komentarzy.