Those of you who have used Vue-element-Admin must know that the configuration of routing is directly related to the display of the navigation menu in the sidebar. Thanks to this design idea, almost most background frameworks adopt this scheme, including the Fantastic-admin middle background framework I wrote.

The obvious problem with this approach is that in order to achieve multiple levels of sidebar navigation menus, you need to configure the route as multiple levels of nesting. Once you go beyond two levels and reach three or more levels, you need to add an Empty layout page (empty.vue) for the Component to use just to generate the hierarchical menu. There is a problem. Because keep-alive is handled on Layout, routes that exceed two levels become difficult to handle and there is no relatively perfect solution.

Before we think and solve this problem, let’s take a look at the general structure of the page:

+------------------------------+
| Layout                       |
|  +------------------------+  |
|  | Empty                  |  |
|  |  +------------------+  |  |
|  |  | Page             |  |  |
|  |  +------------------+  |  |
|  +------------------------+  |
+------------------------------+
Copy the code

Firstly, keep-alive is processed on Layout. If Empty is not cached, the pages under Empty cannot be cached. If Empty is cached, all pages in Empty will be cached and cannot be cleared as needed. I believe that those who have been in contact with the students must feel the pit.

solution

In fact, there is a relatively clear and simple solution, since it is no problem to cache the secondary route, and it does not make much sense to exceed the secondary level of the intermediate page, then why not directly process the route into the secondary level, so that the page display is the secondary structure.

+------------------------------+ +------------------------------+ | Layout | | Layout.vue | | +------------------------+  | | +------------------------+ | | | Empty | | +----------> | | Page | | | | +------------------+ | | | | | | | | | Page | | | | | | | | | +------------------+ | | | | | | | +------------------------+ | | +------------------------+ | +------------------------------+ +------------------------------+Copy the code

It should be noted that the route configuration is still in the form of multi-level nesting, and this configuration is not the final route to be registered, but only provides the sidebar navigation menu for use, and generates a data for dynamic route registration. If you do not understand the diagram, you can see the following two sets of data.

// Raw data (for sidebar navigation menu)
{
    path: '/users'.meta: {
        title: 'User Management'
    },
    children: [{path: 'clients'.meta: {
                title: 'Customer Management'
            },
            children: [{path: 'list'.meta: {
                        title: 'Customer List'}}, {path: 'detail'.meta: {
                        title: 'Customer Details'}}]}// Processed data (used to dynamically register routes)
{
    path: '/users'.meta: {
        title: 'User Management'
    },
    children: [{path: 'clients/list'.meta: {
                title: 'Customer List'}}, {path: 'clients/detail'.meta: {
                title: 'Customer Details'}}}]Copy the code

Routing data can be handled with a recursive function, but that’s not enough because breadcrumb navigation needs to be handled.

The original breadcrumb navigation can obtain the information of each level of nested pattern through $route.matched, but when the route is processed into two levels, it cannot be displayed through $route.matched, so it needs to process the breadcrumb navigation information while processing the routing data. It will end up like this:

{
    path: '/users'.meta: {
        title: 'User Management'
    },
    children: [{path: 'clients/list'.meta: {
                title: 'Customer List'.breadCrumb: [{path: '/users'.title: 'User Management' },
                    { path: 'clients'.title: 'Customer Management' },
                    { path: 'list'.title: 'Customer List'}]}}, {path: 'clients/detail'.meta: {
                title: 'Customer Details'.breadCrumb: [{path: '/users'.title: 'User Management' },
                    { path: 'clients'.title: 'Customer Management' },
                    { path: 'detail'.title: 'Customer Details'}]}}Copy the code

This way, $route.meta. Breadcrumb gives you the complete breadcrumb navigation information for any route. The final effect is as follows:

As can be seen from the picture, this scheme still has certain limitations, that is, after the route is processed into two levels, multi-level nesting relationship does not exist, that is, no code can be written in Empty, because it will be ignored, and only the top-level and deepest bottom-level routes are retained.

Of course, considering the actual situation, this limitation is not a big problem, because in the background system, its modules are relatively independent, even though the navigation menu of the sidebar is nested hierarchy, the content display area on the right side is almost independent module display, without nesting.

The sample code

This article mainly discusses the implementation ideas, the relevant code can be viewed in Fantastic-admin, the core code is here, click to view.