代码之家  ›  专栏  ›  技术社区  ›  angelique000

对于非常大的Web应用程序,Vue路由器的最佳实践是什么?

  •  37
  • angelique000  · 技术社区  · 6 年前

    我必须用许多不同的模块(如todo模块、文档模块和针对管理员用户的大型用户管理模块)创建一个Web应用程序。总页数为>而且每个用户的模块访问权限都不同。

    我正在与 拉雷维尔 Vue路由器

    但最好的做法是什么?

    1. 创建一个SPA应用程序,每个应用程序都有一个大型vue路由器?
    2. 每个模块都有一个单独的“SPA”(带和自己的vue路由器)?
    3. 或者其他建议。。。?
    3 回复  |  直到 6 年前
        1
  •  38
  •   Harshal Patil    6 年前

    有点晚了,但我会尽力回答这个问题。这更像是一个架构问题,而不仅仅是路由级别的问题。

    TLDR: 您将需要多种方法的混合。一种方法不合适。

    1、路由方式

    首先,你应该决定是否 HTML 5 history mode or hash mode 现在是2018年,我明确建议您使用HTML5历史模式。

    如果使用历史记录模式,则意味着客户端路由器需要与服务器端路由器同步工作。

    2、微型前端

    我不知道你是否知道,但是 micro-frontends 是您要查找的术语。基本上,这是你的第一条种族隔离线。您应该将应用程序拆分为多个较小的应用程序。每个应用程序都有其根组件, 路由器 ,模型,服务等。您将共享许多组件(当然,word 非常大 应用程序很重要。我是认真的。)

    3、单一回购考虑事项

    如果您选择继续使用微型前端,那么您可以考虑 mono-repo setup 使用Lerna或Builder。

    4、路由模块-初始化

    无论微应用如何,你的应用都应该有一个起点- main.js index.js 。在此文件中,您应该初始化所有单例内容。典型Vue中的主要单例实体。js应用程序是 根组件 ,则, 数据存储区 ,则, 路由器

    您的路由模块将与任何组件分离。在此条目文件中导入路由模块并在此处初始化。

    5、路由模块-实现

    路由模块应进一步拆分为更小的模块。使用简单的函数和ES模块可以做到这一点。每个函数将负责返回 RouteConfig 对象这就是它的外观:

    const route: RouteConfig = {
        path: '/some-path',
        component: AppComponent,
        children: [
            getWelcomeRoute(),
            getDashboardRoute()
        ]
    };
    
    function getWelcomeRoute(): RouteConfig {
        return {
            name: ROUTE_WELCOME,
            path: '',
            component: WelcomeComponent
        };
    }
    

    在路由级别,您应该考虑延迟加载模块。这将节省预先加载的许多字节:

    function getLazyWelcomeRoute(): RouteConfig {
    
        // IMPORTANT for lazy loading
        const LazyWelcomeComponent = () => import('views/WelcomeComponent.vue');
    
        return {
            name: ROUTE_WELCOME,
            path: '',
            component: LazyWelcomeComponent
        };
    }
    

    除非使用像Webpack或Rollup这样的捆绑程序,否则无法执行此操作。

    5、布线模块-防护

    这非常重要 警卫是你应该处理授权的地方。使用Vue。js,可以编写组件级路由保护。 但我的建议是不要这样做 .只有在绝对必要时才这样做。这基本上是一种关注的分离。您的路由模块应具备应用程序授权的知识。从技术上讲,授权存在/适用于路线,而不是组件。这就是为什么我们将路由创建为一个单独的模块的原因。

    我假设您正在为非常大的应用程序使用某种类型的数据存储,如Redux或Vuex。如果要编写路由级防护,则需要咨询Redux/Vuex存储区的数据,以做出授权决策。这意味着您需要将存储注入路由模块。最简单的方法是将路由器初始化封装到如下函数中:

    export function makeRouter(store: Store<AppState>): VueRouter {
        // Now you can access store here
        return new VueRouter({
            mode: 'history',
            routes: [
                getWelcomeRoute(store),
            ]
        });
    }
    

    现在,您可以从入口点文件简单地调用此函数。

    6、路由模块-默认路由

    记住要定义一个默认的全覆盖路由,以便向用户显示通用/智能404消息。

    7、路由模块-路由数据

    既然我们真的在谈论 非常大 应用程序中,最好避免直接访问组件中的路由器。相反,保持路由器数据与数据存储同步,如 vuex-router-sync 。这样做可以避免大量令人痛苦的错误。

    8、布线模块-副作用

    您将经常使用 $router.replace() $router.push() 在您的组件中。从组件的角度来看,这是一种副作用。相反,处理组件外部的编程路由器导航。为所有路由器导航创建一个中心位置。向该外部实体发送请求/操作,以便为您处理这些副作用。太长,读不下去了不要直接在组件内进行布线副作用。它将使您的组件坚固且易于测试。在我们的例子中,我们使用redux observable来处理路由的副作用。

    我希望这涵盖了 非常大 缩放应用程序。

        2
  •  4
  •   Arielle Nguyen    6 年前

    如果您使用SPA应用程序,请确保您正在使用以下做法:

    1. 延迟加载/异步组件。我们通常对静态资产进行延迟加载。本着同样的精神,我们只需要在访问路由时加载组件。Vue仅在需要渲染组件时触发factory函数,并将缓存结果以备将来重新渲染。
    import MainPage from './routes/MainPage.vue'
    const Page1 = r => require.ensure([], () => r(require('./routes/Page1.vue')))
    
    const routes = [
      { path: '/main', component: MainPage },
      { path: '/page1', component: Page1 }
    ]
    
    1. 组合路由:(与上文相关)例如,在以下情况下,在同一块和包中输出2条路由,导致在访问任一路由时延迟加载该包。
    const Page1 = r => require.ensure([], () => r(require('./routes/Page1.vue')), 'big-pages')  
    const Page2 = r => require.ensure([], () => r(require('./routes/Page2.vue')), 'big-pages')
    
        3
  •  1
  •   manoi    6 年前

    Nuxt可以帮助您做到这一点。它会将您的文件夹结构动态生成到路由器配置文件。看看 https://nuxtjs.org/guide/routing

    它甚至比路由具有更多的帮助功能。但特别是对于大型应用程序,通常需要在nuxt上设置