在动态路由中绑定多实例组件

最近在开发中遇上了一个问题,我们有十几个上传的页面,功能几乎一致,只有内部的文本和一个日期选择器不一样,但是BA又希望可以通过url访问到每个页面,技术上又不希望真的去写十几个一样的页面——这也太蠢了。于是就想到了通过一份配置文件,提供一个页面信息的list,然后遍历这个list,动态生成route信息和组件,并添加到路由中:

配置列表:

const pages: Page[] = [
  {
    title: 'AAA',
    url: '/home/aaa',
  },
  {
    title: 'BBB',
    url: '/home/bbb',

  },
  ...
]

配置列表转换成路由信息:

const list = pages.map((page) => {
  return {
    path: page.url,
    name: page.title,
    component: () => import('@/components/TestPage.vue'),
    meta: { data: page }
  };
});

添加路由信息:

const routes = [
  {
    path: '/',
    redirect: '/home',
    component: () => import('@/pages/IndexPage.vue'),
    children: [
      {
        path: '/home',
        name: 'Home',
        component: () => import('@/pages/Home.vue'),
        children: [
          {
            // other route info
          },
          ...list // 把生成的路由信息添加到子路由里
        ]
      },
     ...
    ]
  }
];

Home中添加动态路由

<template>
  <router-view />
</template>

但是这样有一个问题,如果在aaa页面上修改了某个值,那么在bbb上这个值也会跟着被修改,这是因为pages中定义的所有路由,绑定的其实是同一个组件实例。为了解决这个问题,一个简单的解决方法就是把组件由单例的,改为多实例的,即每个url都绑定一个自己的组件实例。

首先需要修改动态生成的路由信息,增加key,强制vue-router为每个不同的路由配置创建一个新的组件实例:

const list = pages.map((page) => {
  return {
    ...
    meta: { data: page },
    key: page.title
  };
});

同时,还要修改Home,来应用key

<template>
  <router-view v-slot="{ Component, route }">
    <keep-alive>
      <Component :is="Component" :key="route.name" />
    </keep-alive>
  </router-view>
</template>

这样,每个url都有一个自己的组件实例,防止互相之间修改数据。这个解决方法并不算很好,如果列表里的信息很多,会生成很多组件,对性能产生影响

posted @ 2023-09-11 15:25  maurrinho  阅读(22)  评论(0编辑  收藏  举报