对于超大型 Web 应用程序,最好的 Vue-Router 实践是什么?

What is the best Vue-Router practice for very large webapplications?

我必须制作一个包含许多不同模块(如待办事项模块、文档模块和用于管理员用户的大型用户管理模块)的网络应用程序。总页数>100,每个用户模块访问权限不同

我正在使用 LaravelVue-router.

但是最好的做法是什么?

  1. 创建一个 SPA 应用程序,用 1 个大型 vue-router 来处理一切?
  2. 每个模块都有自己的 "SPA"(有自己的 vue-router)?
  3. 或者另一个建议...?

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

  1. 惰性 loading/async 组件。我们通常对静态资产进行延迟加载。本着同样的精神,我们只需要在访问路由时加载组件。 Vue 只会在需要渲染组件时触发工厂函数,并缓存结果以备将来重新渲染。
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. Combining routes:(与上文相关)例如,在下面的情况下,在同一个chunk和bundle中输出了2条路由,导致在访问任一路由时该bundle被延迟加载。
const Page1 = r => require.ensure([], () => r(require('./routes/Page1.vue')), 'big-pages')  
const Page2 = r => require.ensure([], () => r(require('./routes/Page2.vue')), 'big-pages')

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

它的帮助功能比路由还要多。但特别是对于一般的大型应用程序来说,一个想法是在 nuxt

上设置

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

TLDR: You will need a mix of approaches. One approach won't fit.

1。路由模式

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

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

2。微前端

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

3。单一回购注意事项

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

4。路由模块 - 初始化

无论是哪种微应用,您的应用都应该有一个起点 - main.jsindex.js。在这个文件中,你应该初始化你所有的单例。典型 Vue.js 应用程序中的主要单例实体是 Root ComponentData StoreRouter

您的路由模块将与任何组件分开。在这个入口文件中导入路由模块,并在这里初始化。

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。路由模块 - Guard

这个很重要 守卫是你应该处理你的授权的地方。有了Vue.js,就可以编写组件级路由守卫了。 但我的建议是不要这样做。只有在绝对必要时才这样做。它基本上是关注点分离。您的路由模块应该知道您的应用程序的授权。从技术上讲,对路由的授权 exists/applies 比对组件的授权。这就是为什么我们将路由完全创建为一个单独的模块的原因。

我假设您正在为非常大的应用程序使用某种数据存储,例如 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.路由模块 - 默认路由

请记住定义一个默认的包罗万象的路由以向您的用户显示 generic/intelligent 404 消息。

7。路由模块 - 路由数据

因为我们真正谈论的是 非常大的 应用程序,所以最好避免直接访问组件内的路由器。相反,让你的路由器数据与你的数据存储同步,比如 vuex-router-sync 。通过这样做,您将避免痛苦的错误数量。

8。路由模块 - 副作用

您将经常在您的组件中使用 $router.replace()$router.push()。从组件的角度来看,它是一个副作用。相反,在您的组件之外处理程序化的路由器导航。为所有路由器导航创建一个中心位置。向这个外部实体发送一个 request/action 来为你处理这些副作用。 TLDR;不要直接在你的组件中做路由副作用。它将使您的组件坚固且易于测试。在我们的例子中,我们使用 redux-observable 来处理路由副作用。

我希望这涵盖了超大型 规模应用程序路由的所有方面。