首页 > 解决方案 > 如何使用 vue-router 从父路由继承 props

问题描述

我有以下路由器配置,并希望将id路由main.parent转换为整数,然后传递给props: true所有子组件的子组件(给定)。

{
  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: [{
        ...
      }]
    }]
  }]
}

但是,似乎路由函数只真正调用一次(在评估时/:id),而不是在/:id/details评估时。vue-router 中的相关代码似乎证实了这一点。

            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,
            }));
            ...

我想知道是否有人试图解决同样的问题以及他们想出了什么解决方案。理想情况下,我想避免为每条子路线重复道具功能。

标签: javascriptvue.jsvue-router4

解决方案


Vue Router 中没有这样的功能可以通过这种方式将 props 传递给子路由。

相反,您可以使用provide/inject来有效地做到这一点。父母可以provide拥有id财产,任何后代都inject可以:

  1. ParentComponent.vue中,使用toRefs()onprops获得refid道具的反应。
  2. 用于provide()提供id给任何孩子(包括孩子路线)。
  3. 应用keyon<router-view>以确保基于唯一的id.
  4. ChildComponent.vue中,使用inject道具注入id来自步骤 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>

组合 API 演示

选项 API 演示


推荐阅读