Writing problem, the realization of three – level nesting, two – level routing needs to inherit empty template


import Empty from '@/layout/empty.vue' { name: 'One', path: '/one', component: 'Layout', alwaysShow: true, meta: {title: '1 ', icon: 'tool'}, children: [{name: 'Empty', path: '/one/two', Component: Empty, alwaysShow: true, meta: {title: '2 ', icon: 'tool'}, children: [{name: 'Three', path:' one/two/ Three', component: () = > import (' @ / views/three/index), meta: {title: '3', icon: 'build'}}}}]]Copy the code

Empty. vue if you want a level 3 page cache, you must add keep-alive. Otherwise, the cache will not be used

<template>
  <keep-alive :include="cachedViews">
    <router-view :key="key" />
  </keep-alive>
</template>
<script>
export default {
  name: 'Empty',
  computed: {
    cachedViews() {
      return this.$store.state.tagsView.cachedViews
    },
    key() {
      return this.$route.path
    }
  }
}
</script>
Copy the code

The cause of the problem is that the third-level route is not cached

Keep-alive components depend on cachedViews. CachedViews is a state in the store. The logic of cachedViews is in SRC /layout/TagView, AddViewTags are called when the route changes, and addViewTags are cached based on the matching route name attribute. When a level-3 route is used, only the name of the level-3 route can be obtained. The template name inherited by the level-2 route will be lost. Keep-alive does not cache the template name.


The solution

Add the name of the secondary menu to the cache in tagsview.js

const state = {
  visitedViews: [],
  cachedViews: ['Empty']
}
Copy the code

The above method can solve the caching problem, but then the problem is that the virtual DOM still exists after the three-level page is closed, resulting in bad consequences. First, the memory occupies too much and wastes resources. Then, when you switch routes and right-click on TAB headers, you call created and Mounted pages that are not clear

At that time, the blogger was also puzzled that when there was only the home page left, when the new page was opened, there were many interface requests for pages that had been closed before in the NetWork

With vueDevTools, the truth came out

The Emptty dom is added to the \ SRC \layout\components\ appmain. vue and empty.vue templates with keep-alive. The parent template of all level 3 pages is Empty, which results in an Emptty whenever a level 3 page is opened, and because of the need for level 3 route caching, it is impossible to know exactly when the level 2 template cache needs to be cleared

Therefore, the current solution of the blogger is to upgrade the three-level route to the second-level route into the following format, which is still the effect of the three-level route for the path display

{name: 'One', path: '/ One', component: 'Layout', alwaysShow: true, meta: {title: 'level ', icon: 'tool'}, children: [ { name: 'Three', path: '/one/two/three', component: () =>import('@/views/three/index'), meta: { title: '/ ', icon: 'build'}}]}Copy the code

If the route is set to get data from the interface, it needs to be processed by the store in permission-js when requesting the route

// Iterate over the routing string passed in the background, Function filterAsyncRouter(asyncRouterMap, lastRouter = false, Type = false) {return json.parse (json.stringify (asyncRouterMap)).filter(route => {// Processes routes required by vue-router If (type && route.children) {route.children = filterChildren(route.children)} // If (lastRouter && rout.path.indexof (' HTTP ') === -1) {route. Path = lastRouter. Path + '/' + route If (route.com === 'Layout') {route.com = Layout} else if (route.com == 'Layout') {route.com = Layout} else if (route.component === 'Empty') { route.component = Empty } else { route.component = loadView(route.component) // Route.children is a string in this case a string to component object}} // If there is a subset of route.children! = null && route.children && route.children.length) { route.children = filterAsyncRouter(route.children, route, type) } return true }) } // function filterChildren(childrenMap, lastRouter = false) { var children = [] JSON.parse(JSON.stringify(childrenMap)).forEach((el, index) => { if (el.children && el.children.length) { if (el.component === 'Empty') { el.children.forEach(c => { c.path =  el.path + '/' + c.path if (c.children && c.children.length) { children = children.concat(filterChildren(c.children, c)) return } children.push(c) }) childrenMap.splice(index, 1) return } } if (lastRouter) { el.path = lastRouter.path + '/' + el.path } children = children.concat(el) }) return Children} export const loadView = view => {// route lazy loading return () => import(' @/views/${view} ') // asynchronous dynamic loading}Copy the code

Note: Since keep-alive and router-view are strongly coupled, the include of keep-alive defaults to the name of the component. Make sure that the router and the View Component of the route have the same name. (Remember to make sure that the name is unique and you don’t want to repeat the name of some component, otherwise you will recursively refer to it and run out of memory.)

Original text – Document

Welcome to pay attention to my public number: Front-end technology war (attention, is the battle of the battle yo)

If you can

My blog

I’m the nuggets

My Jane books

Laravel China