[Vue framework] Vue routing configuration

foreword

In order to see the use of back-end permissions in the front-end, read the vue-element-admin-4.2.1 code to understand; at the same time, learn about the front-end framework and introduce (learn) some of the content in detail. This article mainly looks at each content from main.js, and organizes the relationship between main, router and store.

Code download: vue-element-admin-4.2.1
PS: Although this article is very long, it is actually very simple. Comments have been written on the code, take a look

The code directory structure introduced in this article:
insert image description here

1、main.js

1.1 Code

Here we mainly introduce some main content, css style and mock are not explained.

import Vue from 'vue'
import Cookies from 'js-cookie'
import Element from 'element-ui'
import App from './App'
import store from './store'
import router from './router'
import * as filters from './filters' // global filters

// 使用 `Element` 组件库
Vue.use(Element, {
    
    
  size: Cookies.get('size') || 'medium' // set element-ui default size
})

// register global utility filters 遍历 `filters` 对象的键值对,全局注册过滤器
Object.keys(filters).forEach(key => {
    
    
  Vue.filter(key, filters[key])
})
// 设置生产环境的提示信息为 `false`,避免显示开发环境的提示信息
Vue.config.productionTip = false

// 创建Vue实例
// 请注意,这段代码是Vue.js应用程序的入口文件
new Vue({
    
    
  el: '#app', // 将Vue挂载到id为`app`的DOM元素上
  // 配置路由,就是用我们在router目录中写好的index,传入了 `router` 和 `store` 对象作为参数  
  router, // 路由实例
  store, // 状态管理实例
  render: h => h(App) // 用于渲染根组件,`App` 组件是根组件,渲染`App`组件
})

1.2 el: '#app'

el: '#app'It is one of the configuration items of the instance in Vue.js, which is used to specify the elements mounted by the Vue instance.
In a Vue application, we usually specify a container element in the HTML page to render the content generated by the Vue instance into the container.
This container element can be a divlabel, an element with a unique ID, or any other suitable HTML element.

el: '#app'It is to tell the Vue instance to mount the content generated by it to appthe element with ID in HTML.
This means that the components rendered by the Vue instance will be dynamically inserted into id="app"the elements that the HTML page has.
In the HTML page, we need to ensure that there is an elelement corresponding to the configuration item.

For example, there is an element in HTML <div id="app"></div>,
and then we create a Vue instance and elset its configuration item to '#app', and the content generated by the Vue instance will be rendered into it <div id="app"></div>.
By using elconfiguration items, we can control where the Vue instance is mounted, so that Vue components are rendered into the HTML elements we specify.

1.3 render

In Vue.js, renderit is a configuration item used to define how to render components.
It is a function that receives createElementthe function as a parameter, createElementgenerates a virtual DOM by calling the function, and finally renders it into a real DOM.

Typically, renderfunctions use the shorthand form of an arrow function: (h) => h(Component).
Among them, his createElementthe alias of the function, which is used to create the virtual DOM. Componentis the name of a component or a component options object.
For example, render: h => h(App)specify that Appthe component be rendered on the root element. [Personal understanding App, components should refer to App.vue]

renderConfiguration items can be used in various ways, and the logic in the function can be used to dynamically generate virtual DOM according to actual needs.
This method allows finer-grained control over the rendering process of components, such as conditional rendering, dynamic rendering, etc.
It should be noted that if renderthe function is configured, templatethe and elconfiguration items will be ignored.

2、router

2.1 Code

import Vue from 'vue'
import Router from 'vue-router'
/**
 * 安装路由
 * 显示声明使用Router
 * 在main.js里import router from './router',就是指当前目录下router里的index
 */
Vue.use(Router)

/* Layout */
import Layout from '@/layout'

/* Router Modules */
import componentsRouter from './modules/components'
import chartsRouter from './modules/charts'
import tableRouter from './modules/table'
import nestedRouter from './modules/nested'

/**
 * constantRoutes
 * a base page that does not have permission requirements
 * all roles can be accessed
 * 没有权限要求的基页
 * 所有角色都可以访问
 */
// 用于存储常量路由配置
export const constantRoutes = [
  {
    
    
    // 路由路径
    path: '/redirect',
    // 跳转的组件 使用名为`Layout`的组件
    component: Layout,
    // 该路径在侧边栏中不可见
    hidden: true,
    // 二级路由 定义了该路径下的子路径,即重定向的某些情况
    children: [
      {
    
    
        // 路径为`/redirect`,并以参数的形式传递数据,参数名为`path`;
        path: '/redirect/:path*',
        // 在该路径下使用名为`index`的`redirect`组件
        component: () => import('@/views/redirect/index')
      }
    ]
  },
  {
    
    
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },
  {
    
    
    path: '/auth-redirect',
    component: () => import('@/views/login/auth-redirect'),
    hidden: true
  },
  {
    
    
    path: '/404',
    component: () => import('@/views/error-page/404'),
    hidden: true
  },
  {
    
    
    path: '/401',
    component: () => import('@/views/error-page/401'),
    hidden: true
  },
  // 定义了一个根路径并重定向到Dashboard页面
  {
    
    
    path: '/',
    // 使用名为`Layout`的组件
    component: Layout,
    // 重定向到`/dashboard`路径
    redirect: '/dashboard',
    // 二级路由 定义该路径下的子路径,即`/dashboard`
    children: [
      {
    
    
        path: 'dashboard',
        // 在该路径下使用名为`index`的`dashboard`组件
        component: () => import('@/views/dashboard/index'),
        // 该路径的名称为`Dashboard`
        name: 'Dashboard',
        // 路由元信息 title设置该路由在侧边栏和面包屑中展示的名字;  affix如果设置为true,它则会固定在tags-view中(默认 false)
        meta: {
    
     title: 'Dashboard', icon: 'dashboard', affix: true }
      }
    ]
  },
  ...
]

/**
 * asyncRoutes
 * the routes that need to be dynamically loaded based on user roles
 * 代表那些需求动态判断权限并通过 addRoutes 动态添加的页面
 */
export const asyncRoutes = [
  {
    
    
    path: '/permission',
    component: Layout,
    redirect: '/permission/page',
    alwaysShow: true, // will always show the root menu
    name: 'Permission',
    meta: {
    
    
      title: 'Permission',
      icon: 'lock',
      roles: ['admin', 'editor'] // you can set roles in root nav
    },
    children: [
      {
    
    
        path: 'page',
        component: () => import('@/views/permission/page'),
        name: 'PagePermission',
        meta: {
    
    
          title: 'Page Permission',
          roles: ['admin'] // or you can only set roles in sub nav
        }
      },
      {
    
    
        path: 'directive',
        component: () => import('@/views/permission/directive'),
        name: 'DirectivePermission',
        meta: {
    
    
          title: 'Directive Permission'
          // if do not set roles, means: this page does not require permission
        }
      },
      {
    
    
        path: 'role',
        component: () => import('@/views/permission/role'),
        name: 'RolePermission',
        meta: {
    
    
          title: 'Role Permission',
          roles: ['admin']
        }
      }
    ]
  },

  /** when your routing map is too long, you can split it into small modules **/
  componentsRouter,
  chartsRouter,
  nestedRouter,
  tableRouter,
	...
  {
    
    
    path: '/error',
    component: Layout,
    redirect: 'noRedirect',
    name: 'ErrorPages',
    meta: {
    
    
      title: 'Error Pages',
      icon: '404'
    },
    children: [
      {
    
    
        path: '401',
        component: () => import('@/views/error-page/401'),
        name: 'Page401',
        meta: {
    
     title: '401', noCache: true }
      },
      {
    
    
        path: '404',
        component: () => import('@/views/error-page/404'),
        name: 'Page404',
        meta: {
    
     title: '404', noCache: true }
      }
    ]
  },
	...
  // 404 page must be placed at the end !!!
  {
    
     path: '*', redirect: '/404', hidden: true }
]

Because the code is too long, the above basically introduces object components, defines basic routing and dynamic routing, and the
following code creates routing objects based on the above content

// 定义了一个`createRouter`函数,返回一个新的路由实例;
const createRouter = () => new Router({
    
    
  // mode: 'history', // require service support
  // 定义滚动行为,当切换到新路由时,页面滚动到顶部
  scrollBehavior: () => ({
    
     y: 0 }),
  // 使用之前定义的`constantRoutes`常量作为路由配置
  routes: constantRoutes
})

const router = createRouter()

// 导出`resetRouter`,通过调用 `resetRouter` 函数,可以重新创建和设置路由实例,从而达到重置路由的效果
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
    
    
  const newRouter = createRouter()
  // 将新路由实例的 `matcher` 属性赋值给原有的路由实例的 `matcher` 属性,用于重置(重新设置)路由
  router.matcher = newRouter.matcher // reset router
}

// 配置导出路由,这里的router就是上面定义的createRouter方法,返回一个新的路由实例new Router
export default router

2.2 What is a Router?

In Vue.js, routing (Router) is a mechanism for managing page navigation, which is used to implement page switching and navigation functions in single-page applications (SPA).
Vue provides an official plugin called Vue Router for implementing front-end routing functionality.
Vue Router allows us to map different URL paths to corresponding components by defining routing configurations, and then perform page switching and navigation in the application.

It uses rules and patterns similar to URL paths to decide how to render components and how to respond to user navigation operations.
Routing in Vue serves the following purposes:

  1. Page switching: Through routing, we can render different components into the view of the application according to different URL paths, so as to achieve page switching effects. For example, clicking on a navigation link or using the forward/back buttons will switch to the corresponding component without refreshing the entire page.
  2. Nested routing: Vue Router supports the definition of nested routing, which can use the rendering result of one component as a subcomponent of another component to realize the hierarchical nesting structure of the page.
  3. Parameter passing: Through routing, we can pass parameters in the URL and access them through the routing object in the component. In this way, dynamic page content display can be realized, such as displaying different product detail pages according to different product IDs.
  4. Navigation guard: Vue Router provides the function of navigation guard, which can add some additional logic processing during the routing switching process, such as verifying user permissions, intercepting unlogged users, and so on.

In summary, routing in Vue is a mechanism for managing page switching and navigation in single-page applications. It allows us to render corresponding components into the view according to different URL paths, and provides a wealth of functions and configuration options to handle different page navigation needs.

2.3 What is the function of resetting the route?

It is usually used when reconfiguring and matching routes are required in some scenarios. Here are some common uses for resetting routes:

  1. User login/logout: When a user logs in or out, routing may need to be reconfigured based on the user's identity role. By resetting the route, the old route configuration can be cleared, and new routes can be reloaded, added and matched.
  2. Permission change: When user permissions change, it may be necessary to change the accessible routing pages. Resetting the route can clear the previous permission configuration, reload the new permission configuration, and re-match the route to control the access permission of the page.
  3. Dynamic routing: When you need to dynamically add or remove routes based on specific conditions, you can reset the routes first to clear the old routing configuration, and then re-add the required routes based on specific conditions.
  4. Multi-account switching: In some applications, multiple accounts may be supported to log in and switch. When the user switches accounts, it may be necessary to reconfigure the routing, clear the old routing configuration, and reload the routing configuration of the new account.

The purpose of resetting routes is to reset routes according to new configurations or requirements in specific scenarios. By resetting the routing, the old routing configuration can be cleared so that the new routing configuration can be reloaded and the routing can be re-matched, so as to realize the dynamic update and control of the routing of the application.

2.4 matcher

By assigning matcherthe value of the new routing instance to the original routing instance matcher, the routing can be reset;
the purpose of this is to reset the routing and clear the old routing in some special scenarios, such as when the user logs out or switches roles. Routing configuration to re-add and match new routes

3、store

3.1 Code

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

// 通过Vue.use()方法,全局注册Vuex插件,使得所有的Vue组件都可以使用Vuex状态管理
Vue.use(Vuex)

/**
 * 使用Webpack的require.context()方法来动态导入当前目录下的所有以.js结尾的文件(模块)
 * context()接收3个参数:directory(目录),useSubdirectories(是否递归子目录),regExp(匹配文件的正则表达式)
 * context函数会返回一个函数,通过调用这个函数并传递文件路径,可以获取到具体的模块。
 * 构建工具需要根据文件目录结构动态地引入和处理模块。例如,在Vue项目中,可以使用require.context来自动注册组件
 */
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

/**
 * reduce(回调函数,初始值)函数:一个回调函数【(modules, modulePath) =>{...}】和一个初始值【{}】
 * 对下面代码的解释:
 * modules表示累积器,记录每次=>{}里面执行的结果;modulePath表示当前元素
 * 最开始的modules就是reduce()里面参数的{}
 * modulesFiles.keys()是包含匹配模块路径的字符串数组,例如['./app.js','./permission.js',...]
 * modulesFiles是一个函数,返回一个上下文对象
 */
// 通过循环遍历context.keys()得到的所有模块路径(动态导入的模块),
// 使用reduce()方法将它们合并为一个modules对象,最终形成一个字典{'app': './app.js'}
// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
    
    
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') // 从模块路径中提取出模块名称
  const value = modulesFiles(modulePath) // 动态导入的模块内容对象,通过`modulePath`作为参数传给`modulesFiles`来获取
  modules[moduleName] = value.default // 将每个模块的名称和内容添加到modules对象中
  return modules
}, {
    
    })

// 创建一个Vuex的Store实例,传入modules对象【是state参数】和getters对象作为选项
const store = new Vuex.Store({
    
    
  modules,
  getters
})

// 将store对象作为默认导出,以便其他地方可以引用store对象来访问Vuex中的状态、操作以及getters
export default store

3.2 What is Vuex?

Vuex is the official state management pattern and library for Vue. In complex applications, the state shared between components can become messy and unmanageable.
Vuex enables developers to better organize, track, and manage the state of their applications by providing a centralized state management mechanism.

In Vuex, the state of the application is stored in a global state tree that can be gettersaccessed and mutationsmodified using .
In addition, Vuex also provides actionsfunctions for performing asynchronous operations and modulesdividing the state into modules for easy management and reuse.

By using Vuex, developers can better manage and share state between components and provide a consistent way to track and update the state of the application.
This is especially useful for large applications and applications involving large data streams.

4. Summary✨

After reading the above specific content, it is still easy to be confused about the whole relationship. Here is a summary of the general relationship for sorting out.
insert image description here

Guess you like

Origin blog.csdn.net/weixin_42516475/article/details/131802461