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

时间:2018-04-25 10:33:21

标签: laravel vue.js single-page-application vue-router

我必须使用许多不同的模块(如todo模块,文档模块和管理员用户的大用户管理模块)进行Web应用。总页数是> 100.每个用户的模块访问权限都不同。

我正在使用 Laravel Vue-router

但这样做的最佳做法是什么?

  1. 创建一个SPA应用程序,其中包含1个大型vue-router用于所有内容?
  2. 对于每个模块一个自己的单个“SPA”(有自己的vue-router)?
  3. 或另一个建议......?

3 个答案:

答案 0 :(得分:10)

迟到但我会尽力回答这个问题。这不仅仅是路由级问题,而是一个架构问题。

  

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

1。路由模式

首先,您应该确定是否要使用HTML 5 history mode or hash mode 它是2018年,我绝对建议你使用HTML5历史模式。

如果您使用历史记录模式,则表示您的客户端路由器需要与服务器端路由器同步。

2。微前端

我不确定您是否知道这一点,但micro-frontends是您正在寻找的术语。基本上,这是你的第一线隔离。您应该将应用分成多个较小的应用。每个应用程序都有其根组件,路由器,模型,服务等。您将共享许多组件(当然,单词非常大应用程序很重要。而且我字面意思是它。)

3。单一回购考虑因素

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

4。路由模块 - 初始化

无论微型应用如何,您的应用都应该有一个起点 - main.jsindex.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 等数据存储保持同步。这样做可以节省大量的bug。

8。路由模块 - 副作用

您经常会在组件中使用$router.replace()$router.push()。从组件的角度来看,这是一种副作用。相反,在组件外部处理程序化路由器导航。为所有路由器导航创建一个中心位置。向此外部实体发送请求/操作以便为您处理这些副作用。 TLDR;不要直接在组件中进行路由副作用。它将使您的组件SOLID并易于测试。在我们的例子中,我们使用redux-observable来处理路由副作用。

我希望这涵盖了非常大的比例应用程序的路由的所有方面。

答案 1 :(得分:1)

如果您使用SPA应用程序,请确保您使用这些做法:

  1. 延迟加载/异步组件。我们通常对静态资产进行延迟加载。本着同样的精神,我们只需要在访问路线时加载组件。 Vue仅在需要渲染组件时触发工厂函数,并将缓存结果以供将来重新渲染。
  2. 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个路由,导致在访问任一路由时该捆绑延迟。
    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')
      

答案 2 :(得分:1)

Nuxt可以帮助您。它会动态生成文件夹Structur到路由器配置文件。看看https://nuxtjs.org/guide/routing

它具有比路由更多的帮助功能。但特别是对于大型应用程序来说,一般的想法是设置nuxt