preface

In my previous single-page applications, since static page resources were packaged and dumped on Nginx, and Nginx was only a traffic access layer and could not write business logic, I had to raise a white flag based on “experience” restrictions when the product proposed a feature that required a specific user to access a particular page.

As a result, users are “free” to see unexpected page content via links, and while it is possible to “return the flow to normal” through data restrictions on the back-end interface, or a strong secondary jump after the page has been loaded, the experience of reloading the page after it has been loaded is never very good. Although I tried to do a server rendering through Node, I gave up because it cost too much to directly host static resources.

Fortunately, I recently contacted JEECG, and saw that dynamic routing is so a form, combined with modern front-end framework, so that single page application can also achieve the effect of server side filtering rendering, or gained a lot of knowledge, the next step to expand the explanation.

Common routes and lazy route loading

First of all, through VUE, we will talk about ordinary routing and lazy loading of routes.

Common routing

This is the “very, very basic” use of routing:

import Common from '.. /pages/router/Common.vue';

const routes = [
  {
    path: '/router/common'. component: Common,  }, ]; Copy the code

This approach is simple, but when a project has too many routes, the file becomes too large, affecting the page load. Then there is the “lazy load” approach to routing.

Route lazy loading

Code Splitting mechanism of Webpack:

import Common from '.. /pages/router/Common.vue';

const routes = [
  {
    path: '/router/common'. component: Common,  },  {  path: '/router/lazy'. component: (a)= > import(/*webpackChunkName: "router-lazy"*/ '.. /pages/router/Lazy.vue'),  }, ]; Copy the code

Webpack provides a very powerful module packaging mechanism, we can use the import mode, cut out the specified route module, when accessing the page route to request the JS file.

A simple example is provided below. Note the network request:

Dynamic routing

The above two ways, I used to. However, these routing mechanisms are weak for complex projects or applications that tend to be managed in the background. Because we can’t do specific page access restrictions, as long as you know the address can jump, even if the code is not robust enough, some people will “mess”, after all, are static resources, F12 can see.

Here is a dynamic route loading approach I learned in JeECG that solves the above problems, even in single-page SPA applications. So how do we do that?

beforeEach

We know that vue-Router has beforeEach API for route guard, which can intercept routes. Usually we use this API to determine tokens or some service identifier for jump restriction.

Here, however, we will access specific interfaces to do dynamic routing effects:

router.beforeEach((to, from, next) = > {
  const _vue = router.app;
  fetchDynamicRoutes()
    .then((dynamicRoutes) = > {
      // Assemble new routing
 const newRoutes = normalizeRoutes(dynamicRoutes);  _vue.$router.addRoutes(newRoutes);  next();  })  .catch((err) = > {}); }); Copy the code

FetchDynamicRoutes is a Promise method that encapsulates a back-end request and fetches data from the front-end routing structure, like this:


Standardized routing

Since the data returned by the back end is somewhat different from the front-end routing structure, there is a normalizeRoutes method for consolidation and further optimization through lazy loading.

/ * ** Standardized routing *
 * @param {*} routes
* /
export function normalizeRoutes(routes) {  return routes.map((router) = > {  return {  path: router.path,  component: _parseComponent(router.componentName),  meta: router.meta,  children: Array.isArray(router.children) ? normalizeRoutes(router.children) : [],  };  }); }  / * ** Route parsing * * If routesMap[componentName] does not get a value, the bundled component file will be dynamically loaded * @param {*} componentName * / function _parseComponent(componentName) {  return routesMap[componentName] || (() = > import(/*webpackChunkName: "router-dynamic"*/ `.. /pages${componentName}.vue`)); } Copy the code

This requires a good convention on the front and back ends, because the route data returned by the back end must exist in the front end file.

Adding Status Management (VUEX)

We can’t access the back-end interface every time to get routing data, but we need state management mechanism to make the whole interaction smoother:

router.beforeEach((to, from, next) => {
  const _vue = router.app;
// Get permission route  if (store.getters.permissionList.length === 0) {
    fetchDynamicRoutes()
 .then((dynamicRoutes) => {  const newRoutes = normalizeRoutes(dynamicRoutes);  _vue.$router.addRoutes(newRoutes);  store.commit('SET_PERMISSIONLIST', newRoutes);  store.commit('SET_SIDE_MENUS', newRoutes[0].children);  next(to.path);  })  .catch((err) => {  console.log(err);  });  } else {  next();  } }); Copy the code

We can use user Logout or the backend unified interface to clear the current authorized route data. If we do not make the front-end cache as much as possible, we may use this data for more things, such as the page navigation bar, menu bar:

data() {
  return {
    list: this.$store.getters.sideMenus
  };
},
Copy the code

For example, the menus on the left of the page in my example so far are rendered using a mechanism like this:

The last

In this way, the simple dynamic routing mechanism is completed, although not as strict as the server SSR can do control, but the general level of the project is basically enough.

This can put the vUE in the road by several core knowledge points to run through, jeECG such operation is still very powerful. Sometimes it’s not the implementation of the code that’s limiting us, it’s the programming that gets us out of the business code so that we can have this idea one day, or we’ll have to read a million books.

This article is formatted using MDNICE