javascript - Cum să reacționezi la schimbările de rută în Vue 3, API-ul de compoziție „script setup”?
Acesta este un exemplu de rute pe care le am în aplicația mea:
{
path: "/something",
name: "SomeRoute",
component: SomeComponent,
meta: {showExtra: true},
},
{
path: "/somethingElse",
name: "SomeOtherRoute",
component: SomeOtherComponent,
},
Atunci am următoarea componentă, care, după cum veți observa, are două etichete script, una cu API de compoziție și una fără:
<template>
<div>
This will always be visible. Also here's a number: {{ number }}
</div>
<div v-if="showExtra">
This will be hidden in some routes.
</div>
</template>
<script setup lang="ts">
import type { RouteLocationNormalized } from "vue-router"
import { ref } from "vue"
const number = 5
const showExtra = ref(true)
const onRouteChange = (to: RouteLocationNormalized) => {
showExtra.value = !!to.meta?.showExtra
}
</script>
<script lang="ts">
import { defineComponent } from "vue"
export default defineComponent({
watch: {
$route: {
handler: "onRouteChange",
flush: "pre",
immediate: true,
deep: true,
},
},
})
</script>
Aceasta funcționează corect: atunci când introduc un traseu cu meta: {showExtra: false}, ascunde div-ul suplimentar, altfel îl afișează.
Ceea ce vreau să fac, totuși, este să realizez același lucru folosind doar API-ul de compoziție, cu alte cuvinte să elimin complet al doilea tag <script>. Am încercat asta:
<script setup lang="ts">
import type { RouteLocationNormalized } from "vue-router"
import { ref } from "vue"
import { onBeforeRouteUpdate } from "vue-router"
// ...
// same as before
// ...
onBeforeRouteUpdate(onRouteChange)
</script>
Dar acest lucru nu va funcționa așa cum mă aștept atunci când schimb ruta. Sunt conștient de funcția watch pe care aș putea să o import, dar nu sunt sigur cum să obțin informațiile meta despre rută și cum să împac verificatorul de tipuri.
Răspuns #1
Poți să convertești watcher-ul tău la API-ul de compoziție prin importarea metodei watch din vue
<script lang="ts">
import { defineComponent, vue, watch } from "vue"
import { useRoute } from "vue-router"
export default defineComponent({
setup() {
const route = useRoute()
watch(route, (to) => {
showExtra.value = !!to.meta?.showExtra
}, {flush: 'pre', immediate: true, deep: true})
},
})
</script>
Răspunsul #2
Nu am suficiente puncte pentru a comenta, dar răspunsul acceptat de mai sus are totuși o mică diferență în funcționare.
API de Opțiuni:
watch: {
'$route': {
handler(oldValue, newValue) => {}
}
}
API de compoziție:
setup() {
const route = useRoute();
watch(route, (newValue, oldValue) => {});
}
În API-ul de compoziție, oldValue va fi doar o clonă a lui newValue (același obiect), în timp ce în API-ul de opțiuni, oldValue va fi de fapt ruta anterioară (util în multe scenarii).
