【问题标题】:Vue.js nested routing with default childVue.js 带有默认子节点的嵌套路由
【发布时间】:2017-04-06 15:48:42
【问题描述】:

我对 Vue.js 2 中的默认子路由有疑问。

当我最初访问 localhost/listings 时,它会正确加载 index.vue 和 map.vue 作为孩子。

当我使用 router-link 导航到 localhost/listings/1,然后使用 router-link 返回 localhost/listings 时,它仍然会加载 show.vue 模板。 这不应该发生吗?

我没有导航守卫或任何应该干扰的东西。有没有办法纠正这个问题?

我的路线:

window.router = new VueRouter({
    routes: [

        ...

        {
            path: '/listings',
            name: 'listing.index',
            component: require('./components/listing/index.vue'),
            children: [
                {
                    path: '',
                    component: require('./components/listing/map.vue')
                },
                {
                    path: ':id',
                    name: 'listing.show',
                    component: require('./components/listing/show.vue')
                }
            ]
        },

        ...

    ]
});

【问题讨论】:

    标签: vue.js vuejs2


    【解决方案1】:

    在 Vue 2.6.11 中,如果父路由被命中,您可以自动重定向到子路由:

    const routes = [
      {
        name: 'parent',
        path: '/',
        component: Parent,
    
        children: [
          {
            name: 'parent.child',
            path: 'child',
            component: Child,
          }
        ],
    
        /**
        * @type {{name: string} | string} Target component to redirect to
        */
        redirect: {
          name: 'parent.child'
        }
      }
    ];
    

    【讨论】:

      【解决方案2】:

      当您使用named routes 并且想要加载包含您的孩子的组件时,您必须为孩子使用名称路由。
      在您的导航菜单链接中,如果您对parent 使用名称路由,则即使子路径没有任何内容,子路径也不会自动加载。
      例如,假设我们有一个用户路由,并且我们希望默认显示组件内的用户列表,因此每当我们转到“/用户”路径时,我们都希望在其中加载一个用户列表作为子路径:

      routes: [
         {
           path: '/user',
           name: 'User',
           component: User,
           children: [
             {path: '', name: 'UserList', component: UserList}, // <== child path is = '';
           ]
         }
        ]
      

      如果您考虑代码,您可能会假设如果您使用名称“User”进行路由,您也可能会在其中获得 UserList,因为父子节点的路径都是相同的。但事实并非如此,您必须选择“UserList”作为名称。 为什么会这样? 因为 Vuejs 加载您所指的确切组件,而不是 url。 你可以实际测试一下,而不是在你的链接中使用命名路由,你可以只引用 url,这一次 vuejs 会加载父子节点没有问题,但是当你使用命名路由时,它不会看url 并加载您所指的组件。

      【讨论】:

        【解决方案3】:

        如果您想要默认子路由,则不应命名“父”路由器,因此请改用:to="{name: 'listing.index'}",使用默认子路由的名称(例如:to="{name: 'listing.map'}")。

        代码应如下所示:

        window.router = new VueRouter({
        routes: [
        
            ...
        
            {
                path: '/listings',
                component: require('./components/listing/index.vue'),
                children: [
                    {
                        path: '',
                        name: 'listing.map'
                        component: require('./components/listing/map.vue')
                    },
                    {
                        path: ':id',
                        name: 'listing.show',
                        component: require('./components/listing/show.vue')
                    }
                ]
            },
        
            ...
        
          ]
        });
        

        【讨论】:

          【解决方案4】:

          也许尝试重新安排孩子,路线是按照他们从上到下匹配的顺序触发的,所以这应该可以解决它:

          window.router = new VueRouter({
              routes: [
          
              ...
          
              {
                  path: '/listings',
                  name: 'listing.index',
                  component: require('./components/listing/index.vue'),
                  children: [
                      {
                          path: ':id',
                          name: 'listing.show',
                          component: require('./components/listing/show.vue')
                      }
                      {
                          path: '',
                          component: require('./components/listing/map.vue')
                      },
                  ]
              },
          
              ...
          
            ]
          });
          

          为了澄清一点,您的path: '' 本质上是一个“包罗万象”,这很可能是为什么当它位于顶部时会立即被发现,因此路由器永远不会进一步传播到:id路线。

          【讨论】:

          • Vue 现在警告这种模式:Named Route 'upload' has a default child route. When navigating to this named route (:to="{name: 'upload'"), the default child route will not be rendered. Remove the name from this route and use the name of the default child route for named links instead.
          • 根据这个github.com/vuejs/vue-router/issues/777#issuecomment-253786416,需要把父路由的名字去掉,给默认的子路由加上名字。 @sadraque-santos 是正确答案。然后,您使用默认子路由名称来呈现该路由的子路由和父路由。
          猜你喜欢
          • 2020-06-01
          • 2023-02-21
          • 2018-05-29
          • 1970-01-01
          • 2016-08-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多