Tengo la siguiente configuración de enrutador y me gustaría que la id
de la ruta main.parent
se convierta en un número entero y luego se pase a los componentes secundarios (propiedades dadas props: true
) para todos los componentes secundarios.
{ path: '/', component: GrandparentComponent, name: 'main', children: [{ path: ':id', component: ParentComponent, name: 'main.parent', props: route => { return { // parse URL id to int id: parseInt(route.params.id, 10) }; }, children: [{ path: 'details', name: 'main.parent.child', component: ChildComponent, props: true, children: [{ ... }] }] }] }
Sin embargo, parece que la función de ruta solo se llama una vez (cuando se evalúa /:id
) y no cuando se evalúa /:id/details
. El código relevante en vue-router parece confirmar esto.
const route = routeToDisplay.value; const matchedRoute = matchedRouteRef.value; const ViewComponent = matchedRoute && matchedRoute.components[props.name]; // we need the value at the time we render because when we unmount, we // navigated to a different location so the value is different const currentName = props.name; if (!ViewComponent) { return normalizeSlot(slots.default, { Component: ViewComponent, route }); } // props from route configuration const routePropsOption = matchedRoute.props[props.name]; const routeProps = routePropsOption ? routePropsOption === true ? route.params : typeof routePropsOption === 'function' ? routePropsOption(route) : routePropsOption : null; ... const component = h(ViewComponent, assign({}, routeProps, attrs, { onVnodeUnmounted, ref: viewRef, })); ...
Me pregunto si alguien trató de resolver el mismo problema y qué solución se le ocurrió. Idealmente, me gustaría evitar duplicar la función de accesorios para cada ruta secundaria.
No existe tal función en Vue Router para pasar accesorios a rutas secundarias de esa manera.
En su lugar, podría usar provide
/ inject
para hacer esto de manera efectiva. El padre provide
la propiedad id
y cualquier descendiente podría inject
:
ParentComponent.vue
, use toRefs()
en props
para obtener una ref
reactiva al id
prop.provide()
para proporcionar esa id
a cualquier hijo (incluidas las rutas secundarias).key
en <router-view>
para asegurarse de que la vista se vuelva a representar en función de la id
única.ChildComponent.vue
, use el accesorio de inyección para inject
la id
del paso 2. // ParentComponent.vue <script> /* Composition API */ import { provide, toRefs } from 'vue' export default { props: ['id'], setup(props) { const { id } = toRefs(props) provide('id', id) }, } /* Options API */ import { toRefs } from 'vue' export default { props: ['id'], provide() { const { id } = toRefs(this.$props) return { id } }, } </script> <template> <router-view :key="id" /> </template>
// ChildComponent.vue <script> export default { inject: ['id'], } </script> <template> <h2>Detail {{ id }}</h2> </template>
No entiendo claramente lo que está preguntando, pero aquí está mi comprensión de sus preguntas:
En lugar de copiar y pegar o repetir el código de la función, puede crear una función y usarla:
const parseUrlIdtoInt = (route) => ({ id: parseInt(route.params.id, 10) }); // ... { path: '...' props: parseUrlIdtoInt, children: [ { path: '...', props: parseUrlIdtoInt } ] } //...
Si la propiedad props
se especifica en la configuración del enrutador, Vue Router pasa automáticamente los accesorios.
- Con la opción props habilitamos pasar props al componente - Con la función props controlamos cómo y qué prop pasar
// Router configuration { path: '...', name: '...', props: true // or a function 👈 // ... }
Entonces, para acceder a id
prop en su ChildComponent
, puede definir accesorios y usarlos:
API de composición
<script setup> defineProps({ id: Number }); </script>
API de opciones
<script> import { defineComponent } from 'vue'; export default defineComponent({ props: { id: Number, }, }); </script>
$attrs.id
en la plantilla.useRoute()
de Vue Router y acceder a los parámetros: <script setup> import { useRoute } from 'vue-router' const route = useRoute() </script> <template> {{ route.params.id }} </template>