Vue-router 正在更改 url 但不重新渲染组件

问题描述 投票:0回答:2

首先我已经检查并打开了历史模式,我像这样调用

vue-router

const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: routes,
});

我当前所在的路线是

/page/item/8
,我正在重定向到
/page/item/9
。目前 url 发生了变化,但页面没有重新呈现,让我停留在与之前相同的视图上。

这个重定向是这样完成的:

this.$router.push({ name: 'PageItem', params: { itemId: '9' }}).catch(err => {
  // Stop Vue.router throwing an error if a user clicks on a notification with the same route.
  if (err.name !== 'NavigationDuplicated') {
    this.$logger.debug.log(err);
  }
});

有问题的路线是这样的:

import PageWrapper from '@/layouts/PageWrapper';
    
export default [
  {
    path: '/page',
    name: 'page',
    component: PageWrapper,
    children: [
      ... Other Routes ...
      {
        component: () => import(/* webpackChunkName: "page-item" */'@/pages/PageItem'),
        name:      'PageItem',
        path:      '/item/:itemId/:view?',
      },
    ],
  },
];

任何想法,我已经调整了代码以删除识别代码,如果它看起来有点奇怪,我们深表歉意。

vue.js vue-router
2个回答
8
投票

只有

itemId
路由参数在变化。在这种情况下,由于在转换前后使用相同的路由组件,vue-router 将重用现有的路由组件;他们不会被摧毁和重建。因此,如果您在组件
created
mounted
挂钩中加载数据,那么它们将不会在路由更改后再次被调用。相反,您需要使用
beforeRouteUpdate
或观看
$route
进行更改。

如果你想强制组件被销毁并重新创建(不推荐)那么你需要

key
路线上的
<router-view>

<router-view :key="$route.fullPath">

阅读数据获取指南以获取更多信息。


0
投票

此解决方案:https://stackoverflow.com/a/69638787/1330193 并非在所有情况下都适用,因为它会重绘完整的组件树,并重建所有组件上下文。这意味着,每次当您更改

:view
参数时,您都会对带有
:itemId
的项目进行额外的API请求。

例如,如果你想保存父路由的范围(在你的情况下:

/page/item/:itemId
)并且只重绘子路由(在你的情况下:
/page/item/:itemId/:view?
),你可以使用这个解决方案:

  1. 指定,你想在路由配置中查看哪个参数:
import PageWrapper from '@/layouts/PageWrapper';
    
export default [
  {
    path: '/page',
    name: 'page',
    component: PageWrapper,
    children: [
      ... Other Routes ...
      {
        component: () => import(/* webpackChunkName: "page-item" */'@/pages/PageItem'),
        name:      'PageItem',
        path:      '/item/:itemId/:view?',
        meta: {
          watchParam: 'itemId' //
        }
      },
    ],
  },
];
  1. 把它放在你的布局组件中:
<router-view :key="$route.params[$route.meta.watchParam]">

因此,只有当

itemId
参数改变时,路由器才会重新渲染路由的组件。

无论如何,它比 watch 组件的 props 更具声明性。 在我看来,这是一种常见的行为,应该以更原生的方式在 vue-router 库中实现。

© www.soinside.com 2019 - 2024. All rights reserved.