B station cloud E office Vue+SpringBoot front and back end separation project - build vue.js project (1)

Project front-end study notes directory

B station cloud E office Vue+SpringBoot front and back end separation project - build vue.js project

B station cloud E office Vue+SpringBoot front and back end separation project - the front end dynamically obtains the menu directory

Project backend study notes directory

B station cloud E office Vue+SpringBoot front and back end separation project - MVC three-tier architecture to build a background project

Project Description

Project background: Affected by the epidemic, many companies have switched from online to offline office. With the increase in the number of people working online, the advantages of online office gradually become prominent: by automating workflow, saving corporate office costs, realizing green office, and improving office efficiency.

Project introduction: This project implements an online office system to manage daily office affairs: daily process approval, news, notices, announcements, file information, finance, personnel, expenses, assets, administration, projects, mobile office, etc. Through the software, the office system can be managed according to the convenience, and the overall management and operation level can be improved.

Implementation method: This project is based on Vue+Spring Boot to build a front-end and back-end separation project. The front end is built using the open source framework Vue, which is very active in the community. Simply put, the core idea of ​​front-end and back-end separation is that the front-end page calls the back-end restuful api for data interaction through ajax, while a single page application (single page web application, SPA) has only one page, and when the user interacts with the application A web application that dynamically updates the page from time to time.

JSON data is communicated between the front and back ends through the RESTful API. Unlike JSP and the like, the backend does not involve the content of the page itself. When developing, the front-end uses the front-end server (Nginx), and the back-end uses the back-end server (Tomcat). When I develop the front-end content, I can forward the front-end request to the back-end through the front-end server (called reverse proxy ), so that you can observe the results in real time, and you don’t need to know how the backend is implemented, but only need to know the functions provided by the interface.

1. Technical Architecture

 2. Front-end technical architecture

This project adopts the development mode of front-end and back-end separation, and uses Spring Boot to build the back-end. The front-end modules are divided into: login, position management, title management, department management, operator calendar, employee management, salary account management, personal center, online chat

The technologies used in the front end are:

    Project construction: Vue-cli

    State management: Vuex

    Routing management: VueRouter

    UI interface:ElementUI

    Communication framework: Axios

    Front-end syntax: ES6

    Packaging: Webpack

    Live Chat: WebSocket

    Font: font-awesome

    File upload and download: js-file-download

    Online chat open source project: vue-chat

3. Back-end technical architecture

Back-end mainstream development framework: SpringBoot+Spring MVC+MyBatisPlus. Use Spring Security for security authentication and authority management, Redis for caching, RabbitMq for sending emails, use EasyPOI to import and export employee data, and use WebSocket for online chat

    Security framework: Spring Security

    Token: JWT

    Graphic verification code: Kaptcha

    Cache: redis

    Document import and export: EasyPOI

    Message Queuing: RabbitMQ does asynchronous processing, sending emails

    Mail component: Mail

    Live Chat: WebSocket

    File server: FastDFS

    DatabaseMySQL+Redis

1. Build a vue.js project

1. vue introduction

        Although native JS can realize most of the functions, it is either too cumbersome or has defects, so most developers will choose the framework development solution first. In terms of framework, basic knowledge such as life cycle, hook function, virtual DOM, and Diff algorithm must be mastered. Among them, communication between components at different levels, component state management, routing jumps, component performance optimization, etc. should be flexible. degree of use. In front-end project development, we can use Vue to varying degrees according to the actual situation. Projects built using Vue CLI (or written as vue-cli, that is, Vue scaffolding) can best reflect the characteristics of Vue. We can slowly experience this in the following content.

Modular development is to split a large file into many independent small files and import them into different components as needed, which reduces code coupling and improves code reusability. Vue develops a single-page application with only one html entry, and the rest are called components. The real entry point is main.js. Vue: Progressive js framework, gradually implementing new features. Such as modular development, routing, state management, etc.

1.1 axios

Front-end communication framework. Because the boundary of vue is very clear, it is for processing DOM, so it does not have communication capabilities. At this time, it needs to use an additional communication framework to interact with the server; of course, you can also directly use the AJAX communication function provided by jQuery.

1.2 Vue-router

Vue Router is the official routing manager for Vue.js. It is deeply integrated with the core of Vue.js, making it easy to build single-page applications. Included features are:

Nested routing/view tables

Modular, component-based routing configuration

Route parameters, queries, wildcards

View transition effect based on Vue.js transition system

Fine-grained navigation control

Links with auto-activated CSS classes

HTML5 history mode or hash mode, automatically degraded in IE9

custom scrollbar behavior

1.3 webpack

        The main difference between front-end development and other development work is that the front-end is based on multi-language, multi-level coding and organization work, and secondly, the delivery of front-end products is based on the browser, and these resources are run to the browser through incremental loading. , How to organize these fragmented codes and resources in the development environment, and ensure their fast and elegant loading and updating in the browser, requires a modular system.

        webpack is a static module bundler (module bundler) for modern JavaScript applications. When webpack processes an application, it recursively builds a dependency graph that includes every module the application needs, and then packages all of these modules into one or more bundles. The idea of ​​webpack: everything is a module, that is, webpack is not only modularized by JavaScript, but also resources such as CSS, pictures, and fonts also need to be modularized. Webpack: Module packager, the main function is to package, compress, merge and load in order. Such as packaging ES6 into ES5

        In the webpack configuration file, main.js is set as the entry file, and our project accesses index.html by default. This file perfectly overlaps with the container in the App.vue component, that is, the component is mounted on the index page , and then we only need to build other components. In the App component, we can also introduce, register, and apply other components. We can render other components in the App component through routing, so we only need to pay attention to each component. Perfect function. That is to say, the default page of vue is index.html, and the large component App.vue is mounted in the index, and then all other subcomponents (hello.vue, etc.) belong to the main component App.vue.

1.4 ES6 modules

        Vue is usually written in es6 and exported with export default, which can contain data, life cycle (mounted, etc.), methods (methods), etc. For specific syntax, please refer to the vue.js document. The ES6 standard adds a module system definition at the javascript language level. The design idea of ​​ES6 modules is to be as static as possible, so that the dependencies of the modules, as well as the input and output variables can be determined at compile time. Both CommonJS and AMD modules can only determine these things at runtime.

1.5 UI framework

Element-UI, launched by Ele.me

1.6 vuex

A state management pattern developed specifically for applications

npm install vuex --save

Create a new store directory in the src directory, create a new index.js file, and import it into main.js

Install vuex start error "export 'watch' was not found in 'vue'

If your vue version is 2.X, you can solve it by upgrading vuex to 3.XX

npm install --save [email protected]

If your vue version is 3.X, you can solve it by upgrading vuex to 4.XX

npm install --save [email protected] npm install --save [email protected]

2. Build the vue.js project

2.1 Environment preparation

Install Node.js (>=6.x, preferred 8.x) This project is version v14.18.0

2.2 Install Vue CLI

Because you need to use npm to install Vue CLI, and npm is integrated in Node.js, so the first step we need to install Node.js, visit the official website Node.js , you can download it from the home page.

After the download is complete, run the installation package and follow the next step.

Then enter node -v in cmd to check whether node is installed successfully.

Enter npm -v to view the npm version number

Enter npm -g install npm to update npm to the latest version.

After that, install the scaffolding with npm install -g vue-cli . (This project uses version 2.9.6)

Note that the 2.x version of Vue CLI is installed in this way, and the latest version needs to be installed through npm install -g @vue/cli. The new version can use the graphical interface to initialize the project and add the content of project health monitoring, but the project dependencies created with the new version do not match this tutorial, and it is troublesome to toss.

Taobao mirror accelerator cnpm installed Node.js

In most cases, use npm, and use cnpm if you can’t install it

npm install cnpm -g

或npm install --registry=https://registry.npm.taobao.org

3. Build the front-end project

The general method builds the project directly using the command line.

Then execute the command vue init webpack yeb, where webpack uses webpack as a template to refer to the generated project, and can also be replaced with parameters such as pwa and simple, which will not be described here.

There will be some prompts during the execution of the program. You can press Enter all the way according to the default settings, or you can modify it as needed. For example, if the following picture asks me if the project name is wj-vue, just press Enter to confirm.

Here you will also be asked whether to install vue-router, you must choose yes, that is, press Enter or press Y, vue-router is the key for us to build a single-page application.

And whether to use es-lint, select N.

Then wait for the project to build and it will be OK.

The project folder is generated in the workspace directory, and you need to execute npm install in this folder, npm run build and then execute npm run dev

Visit http://localhost:8080 , view the webpage demo, and you're done!

Note: In the vue project, sometimes you need to execute npm run serve to start the project, and sometimes you need to use npm run dev. What is the difference?

the difference

By default, dev is the command supported by [email protected] by default ;

By default, serve is the command supported by [email protected] and above.

4. Vue project structure analysis

├── build --------------------------------- Project construction (webpack) related configuration files, configuration parameters and so on , generally do not move

│ ├── build.js -------------------------- webpack packaging configuration file

│ ├── check-versions.js ------------------------------ Check npm, nodejs version

│ ├── dev-client.js ---------------------------------- Setting environment

│ ├── dev-server.js ---------------------------------- Create express server and configure middleware , which starts a hot-reloadable server for development projects

│ ├── utils.js --------------------------------------- Configure the resource path, Configure css loader

│ ├── vue-loader.conf.js ----------------------------- Configure css loader, etc.

│ ├── webpack.base.conf.js --------------------------- webpack basic configuration

│ ├── webpack.dev.conf.js ---------------------------- webpack settings for development

│ ├── webpack.prod.conf.js --------------------------- webpack settings for packaging

├── config ----------------------------------- Configuration directory, including port number, etc. We can use the default for beginners.

│ ├── dev.env.js -------------------------- Development environment variables

│ ├── index.js ---------------------------- project configuration file

│ ├── prod.env.js ------------------------- production environment variables

│ ├── test.env.js ------------------------- test environment variables

├── node_modules ---------------------------- npm loaded project dependent modules

├── src ------------------------------------- The directory we want to develop, basically Everything you do is in this directory.

│ ├── assets ------------------------------ Static files, place some pictures, such as logo, etc.

│ ├── components -------------------------- Component directory, store component files, can not be used.

│ ├── main.js ----------------------------- main js

│ ├── App.vue ----------------------------- project entry component, we can also directly write the component here, and The components directory is not used.

│ ├── router ------------------------------ routing

├── static ---------------------------- Static resource directory, such as pictures, fonts, etc.

├── .babelrc--------------------------------- babel configuration file

├── .editorconfig---------------------------- editor configuration

├── .gitignore----------------------------- Configure files that git can ignore

├── index.html ------------------------------ Home page entry file, you can add some meta information or statistical code of.

├── package.json ---------------------------- node configuration file, which records some commands and dependencies and a brief project description information

├── .README.md------------------------------- Project documentation in markdown format. Write how you want, if you don’t know how to write, refer to the projects with many stars on github to see how they write

Detailed explanation of main documents

4.1 src - [project core file]

In the vue-cli project, the src folder must be mastered, because basically everything to be done is in this directory.

4.2 index.html - [Homepage]

index.html is the same as other html, but generally only defines an empty root node. The instance defined in main.js will be mounted under the root node, and the content will be filled by vue components, and the built file will be automatically injected , which means that other content we write will be displayed in this div. There is only one html file in the whole project, so this is a single-page application. When we open this application, there may be many pages on the surface, but in fact they are all in one div.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>vuedemo</title>
  </head>
  <body>
      <!-- 定义的vue实例将挂载在#app节点下 -->
    <div id="app"></div>
  </body>
</html>

4.3 App.vue - [root component]

This file is called the "root component" because other components are included in this component. A .vue file is a custom file type, similar in structure to html, and a .vue file is a vue component.

A vue page usually consists of three parts: template (template), js (script), style (style)

<!-- 模板 -->
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view></router-view>
  </div>
</template>

<!-- script -->
<script>
export default {
  name: 'app'
}
</script>

<!-- 样式 -->
<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

【template】

The template can only contain one parent node, that is to say, there can only be one top-level div (for example, in the above code, the parent node is the div whose parent node is #app, which has no sibling nodes). There is also a <div id="app"> here, but it has nothing to do with the one in index.html. This id=app just corresponds to the following css.
<router-view></router-view> is a sub-routing view, and all subsequent routing pages are displayed here. To make a metaphor, <router-view> is similar to a slot. When jumping to a certain route, the page under the route is inserted in this slot for rendering and display.

【script】

The content in the <script> tag is the script of the component, that is, the js code. The export default is the syntax of ES6, which means to export this component as a whole, and then you can use import to import the component. The content in curly brackets is the relevant properties of this component.
Vue is usually written in es6 and exported with export default, which can contain data, life cycle (mounted, etc.), methods (methods), etc. For specific syntax, please refer to the vue.js document.

【style】

The style is wrapped by the style tag, which affects the whole world by default. If you want to define the scope to only work under this component, you need to add scoped to the tag. If you want to import external css files, you first need to install the css-loader dependency package for the project. Open cmd, enter the project directory, enter npm install css-loader, and press Enter. After the installation is complete, you can import the required css files under the style tag, for example:

<style>
    import './assets/css/public.css'
</style>

4.4 main.js——[entry file]

main.js mainly introduces the Vue framework, root components and routing settings, and defines the Vue instance. The following components: {App} is the imported root component App.vue. Plug-ins can also be introduced later, of course, the plug-ins must be installed first.
Earlier we said that <div id="app"> in App.vue has nothing to do with <div id="app"> in index.html, so how do these two files connect? Let's look at the code of the entry file main.js

/*引入vue框架*/
import Vue from 'vue'
/*引入根组件*/
import App from './App'
/*引入路由设置*/
import router from './router'

/*关闭生产模式下给出的提示*/ 
Vue.config.productionTip = false

/*定义实例*/ 
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

Several modules are imported at the top, among which the vue module is in node_modules, App is the component defined in App.vue, and router is the route defined in the router folder. Vue.config.productionTip = false , the function is to prevent vue from generating production tips at startup. In this js file, we create a Vue object (instance), and the el attribute provides a DOM element that already exists on the page as the mounting target of the Vue object, here through <div id="app in index.html The id="app" in "><div> and the "#app" here are mounted. router means that the object contains Vue Router and uses the routes defined in the project. components indicates the Vue components contained in the object, and template uses a string template as the identifier of the Vue instance, which is similar to defining an html tag.

5. Related package installation

5.1 Install Element-UI

The official address of Element is http://element-cn.eleme.io/#/zh-CN
1. Install Element
According to the description of the official document, under the project folder, execute npm i element-ui -S to get
here Insert picture description
2. Importing Element
Importing is divided into two modes: full import and on-demand import. On-demand import can reduce the size of the project. Here we choose full import.
According to the documentation, we need to modify main.js as follows

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

5.2 install axios

Go to the project folder and execute
npm install --save axios to install this module.

5.3 Install Vuex

Vuex, it is a state management solution specially developed for Vue, where we can define the variables and methods that need to be passed and used in each component. I haven’t used it before, so it’s a headache to pass values ​​from different components, and I have to write a lot of redundant code to call the values ​​​​of different components, so I recommend that you get familiar with this management method from the beginning.

run npm install vuex --save

After that, create a folder store in the src directory, and create a new index.js file in the directory, and introduce vue and vuex in the file, the code is as follows:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

5.4 Install VueRouter

npm install vue-router --save-dev

Vue-router is the official routing plugin of Vue.js. It is deeply integrated with vue.js and is suitable for building single-page applications. Vue's single-page application is based on routing and components. Routing is used to set access paths and map paths and components.

Under the router folder, there is an index.js, which is the routing configuration file. Multiple routes can be set, such as '/index', '/list', etc. Of course, the component must be introduced first, and then the route should be set for the component.

5.5 Install font-awesome

npm install font-awesome

2. Login page design

1. Page style design

In order to design the interface, what we need to focus on is the html inside the <template> tag and the css inside the <style> tag. We usually use Form to make the login box, open the Element component document (http://element-cn.eleme.io/#/zh-CN/component/), and find that it provides us with a wealth of Form components, we You can click "Show Code" to copy the part we need.

However, it seems that there is no form that is particularly suitable for our application scenario, or these are relatively complicated, and we only need a small part of them. Pull down the page, and you can see the documentation about the properties, events, methods, etc. of this component. According to this documentation, we can build the required form by ourselves.

2. Login page code - views/Login.vue

The verification code returns an image through the backend. Forms bind rules through rules, add attributes to elements through props, and write rules in rules. Validation method: this.$refs.loginForm.validate.

/captcha returns information

/login login return message

After successful login, store the user token to sessionStorage; judge whether the token exists in the request interceptor, and then verify the token for each request. If it exists, request to carry the token and put it in the Authorization parameter; the backend verifies the token.

After the front-end login is successful, use this.$router.replace('/home') to jump to the home page. After the replace method is replaced, clicking the browser back button will not jump to the login page. If the login fails, the backend returns the reason for the failure.

When the user is not logged in, if the user does not visit the login page with http://localhost:8080/#/ , but visits a route that can only be accessed after login, such as http://localhost:8080/#/sys /basic . It needs to be discussed according to the situation: 1. The user may enter the home page address or a wrong address, and let him jump to the home page after successful login; 2. Otherwise, he will jump to the address he entered successfully.

this.$router.replace((path === '/' || path === undefined) ? '/home' : path)

<template>
  <div>
    <el-form
      v-loading="loading"
      element-loading-text="正在登录......"
      element-loading-spinner="el-icon-loading"
      element-loading-background="rgba(0, 0, 0, 0.8)"
      ref="loginForm" :model="loginForm" :rules="rules" class="loginContainer">
      <h3 class="loginTitle">系统登录</h3>
      <el-form-item prop="username">
        <el-input type="text" v-model="loginForm.username" placeholder="请输入用户名"></el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input type="password" v-model="loginForm.password" placeholder="请输入密码"></el-input>
      </el-form-item>
      <el-form-item prop="code">
        <el-input type="text" v-model="loginForm.code" placeholder="点击图片更换验证码"
                  style="width: 250px;margin-right: 5px;"></el-input>
        <img :src="captchaUrl" @click="updateCaptcha">
      </el-form-item>
      <el-button type="primary" style="width: 100%" @click="submitLogin">登录</el-button>
    </el-form>
  </div>
</template>
<script>
  export default {
    name: 'Login',
    components: {},
    props: [],
    data() {
      return {
        // 验证码
        captchaUrl:'api/captcha?time=' + new Date(),//获取响应码后端接口
        loginForm: {
          username: 'admin',
          password: '123',
          code: '',
        },
        loading: false, // 加载中
        checked: true,
        //校验规则,与表单绑定
        rules: {
          username: [{required: true, message: '请输入用户名', trigger: 'blur'}],
          password: [{required: true, message: '请输入密码', trigger: 'blur'}],
          code: [{required: true, message: '请输入验证码', trigger: 'blur'}]
        }
      }
    },
    mounted(){

    },
    methods: {
      // 点击刷新验证码
      updateCaptcha() {
      this.captchaUrl="api/captcha?time="+new Date();

      },
      submitLogin() {
        // 登录
        this.$refs.loginForm.validate((valid) => {
          if (valid) {
            this.loading = true;//准备调登录接口时,出现正在加载
            //第一个参数请求后端的地址,第二个参数,传给后端的数据
            this.postRequest('/login', this.loginForm).then(resp => {
              this.loading = false;//登录成功后关闭
              if (resp) {
                // 存储用户 token 到 sessionStorage
                const tokenStr = resp.obj.tokenHead + resp.obj.token;
                window.sessionStorage.setItem('tokenStr', tokenStr);
                // 跳转到首页
                // this.$router.push('/home') // 路由跳转,可以回退到上一页
                this.$router.replace('/home') // 路径替换,无法回退到上一页

                // 页面跳转
                // 拿到用户要跳转的路径
                let path = this.$route.query.redirect;
                // 用户可能输入首页地址或错误地址,让他跳到首页,否则跳转到他输入的地址
                this.$router.replace((path === '/' || path === undefined) ? '/home' : path)
              }

            })
          } else {
            this.$message.error('请输入所有字段!');
            return false;
          }
        })
      }
    }
  }
</script>
<style>
  .loginContainer {
    border-radius: 15px;
    background-clip: padding-box;
    /*属性规定背景的绘制区域 背景被裁剪到内边距框。 margin: 180 px auto;*/
    margin: 180px auto;
    width: 350px;
    padding: 15px 35px;
    background: #fff;
    border: 1px solid #eaeaea;
    box-shadow: 0 0 25px #cac6c6;
    /*  X轴偏移量 Y轴偏移量 [阴影模糊半径] [阴影扩展] [阴影颜色] [投影方式]; */
  }

  .loginTitle {
    margin: 0 auto 40px auto;
    text-align: center;
  }

  .loginRemember {
    text-align: left;
    margin: 0 0 15px 0;
  }

  /*验证码*/
  .el-form-item__content {
    display: flex;
    align-items: center;
  }
</style>

 In SessionStorage.setItem(), in order to enable axios to obtain token authentication when making the next request, after logging in, get the token and put it in sessionStrorage         

    // Store user token to sessionStorage

                const tokenStr = resp.obj.tokenHead + resp.obj.token;

                window.sessionStorage.setItem('tokenStr', tokenStr);

3. Configure page routing - router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Login from "@/views/Login";

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Login',
      component: Login,
      hidden: true // 不会被循环遍历出来
  },
  ]
})

4. Solve front-end and back-end cross-domain

The front-end port defaults to 8080. Assuming the back-end port is 8081, how does 8080 access the data of 8081? We implement automatic port forwarding through Node.js. The browser's same-origin policy: two pages must have the same protocol (protocol) host (host) port number (port).

When requesting an interface, Access-Control-Allow-Origin, etc. appear, indicating that the request is cross-domain. The way to solve cross-domain in vue: configure the vue.config.js file, if not, create a new one by yourself.

principle:

1. Send the domain name to the local server (localhost:8080)

2. Then the local server requests the real server

3. Because the request is sent from the server, there is no cross-domain problem.

In vue it is done automatically by node.js

4.1 Front-end reverse proxy

Modify main.js

Modify the src\main.js code as follows:

import Vue from 'vue'
import App from './App'
import router from './router'
// 设置反向代理,前端请求默认发送到 http://localhost:8081/api
var axios = require('axios')
axios.defaults.baseURL = 'http://localhost:8081/api'
// 全局注册,之后可在其他组件中通过 this.$axios 发送数据
Vue.prototype.$axios = axios
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})

Modify vue.config.js 

Modify the proxyTable request address to proxy to the backend address 8081 after node.js


    proxyTable: {
      '/': {
        changeOrigin: true, //跨域
        target: 'http://localhost:8081',
        pathRewrite: {
          // '^/api': ''
        }
      },
    
    },

5. Login interceptor

Interceptors , as the name implies, intercept requests, which are request interceptors and response interceptors respectively. The order of execution is: request interceptor -> api request -> response interceptor. The role of the interceptor: a. Count the time required for the API to return data from the initiation of the request; b. Configure public request headers, load pop-up windows, etc.; c. Intercept the response status code and return 400 or 500 from the backend Status code, returns the corresponding error message.

5.1 axios request interceptor request

In the Vue project, we usually use axios to interact with the background data. Axios is a promise-based library that can run in the browser and node environments. The function of the request interceptor request: perform certain operations uniformly before the request is sent, and is often used to process tokens in the request header, etc. 

How to add a request interceptor

axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
})

5.2 Axios response interceptor response

The returned object response contains response.status: Http response code; response.data: the Json object returned by the backend, including response.data.code business logic response code, response.data.message: the response prompt message returned by the backend;

Add response interceptor method

axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
}

5.3 Package request

In the project, we will not use axios directly, but will encapsulate it in one layer. Export the encapsulated request through export, such as defining a postRequest method to receive url and params, and then axios object. Perform the actual interface call operation in axios.

export const postRequest = (url, params) => {
    return axios({
        method: 'post',
        url: `${base}${url}`,
        data: params
    })
}

 5.4 Code implementation src/utils/api.js

import axios from "axios";
import {Message} from "element-ui";
import router from "@/router";

// 请求拦截器
axios.interceptors.request.use(config => {
    // 如果存在 token,请求携带这个 token( 登录的时候 把 token 存入了 sessionStorage )
    if (window.sessionStorage.getItem("tokenStr")) {
        // token 的key : Authorization ; value: tokenStr
        config.headers['Authorization'] = window.sessionStorage.getItem('tokenStr')
    }
    return config;
},error => {
    console.log(error)
})

// 响应拦截器 - 统一处理消息提示
axios.interceptors.response.use(success => {
    // 业务逻辑错误
    if (success.status && success.status === 200) { // 调到接口
        // 后端:500 业务逻辑错误,401 未登录,403 无权访问;
        if (success.data.code === 500 || success.data.code === 401 || success.data.code === 403) {
            Message.error({message: success.data.message})
            return
        }
        if (success.data.message) { // 输出后端 添加成功 之类的信息
            Message.success({message: success.data.message})
        }
    }
    return success.data
}, error => { // 没访问到后端接口
    if (error.response.code === 504 || error.response.code === 404) {
        Message.error({message: '服务器不存在'})
    } else if (error.response.code === 403) {
        Message.error({message: '权限不足,请联系管理员!'})
    } else if (error.response.code === 401) {
        Message.error({message: '您还未登录,请登录!'})
        router.replace('/') // 路由替换
    } else {
        if (error.response.data.message) {
            Message.error({message: error.response.data.message})
        } else {
            Message.error({message: '未知错误!'})
        }
    }
    return
})

// 预备前置路径
let base = '';

// 传送 json 格式的 post 请求
export const postRequest = (url, params) => {
    return axios({
        method: 'post',
        url: `${base}${url}`,
        data: params
    })
}

// 传送 json 格式的 get 请求
export const getRequest = (url, params) => {
    return axios({
        method: 'get',
        url: `${base}${url}`,
        data: params
    })
}

// 传送 json 格式的 put 请求
export const putRequest = (url, params) => {
    return axios({
        method: 'put',
        url: `${base}${url}`,
        data: params
    })
}

// 传送 json 格式的 delete 请求
export const deleteRequest = (url, params) => {
    return axios({
        method: 'delete',
        url: `${base}${url}`,
        data: params
    })
}

5.5 main.js globally introduces encapsulation requests

The method is introduced globally through main.js and then used through a plug-in. Use the form of this.putRequest(url, params) when calling

import {postRequest} from "@/utils/api";
import {putRequest} from "@/utils/api";
import {getRequest} from "@/utils/api";
import {deleteRequest} from "@/utils/api";
Vue.prototype.postRequest = postRequest
Vue.prototype.putRequest = putRequest
Vue.prototype.getRequest = getRequest
Vue.prototype.deleteRequest = deleteRequest

6. Front-end routing navigation guard

The development of the login page seems to be relatively complete, but in fact it is not finished, because this login page is actually useless, and others can bypass the login page by directly entering the URL of the home page. In order for this to work, we also need to develop an interceptor. Use the hook function to determine whether to intercept the function and the function that will be called at certain times. Here we use router.beforeEach(), which means calling before visiting each route. to is the route to go; from is the route from where; next() releases.

Get the user's token through sessionStorage.getItem('user'). If the token does not exist, you need to log in.

When judging whether it is an if (to.path == '/') landing page, if yes, let it go, otherwise log in according to the route specified by the user;

Supplement main.js

// 使用 router.beforeEach 注册一个全局前置守卫
router.beforeEach((to, from, next) => {
  // to 要去的路由; from 来自哪里的路由 ; next() 放行
  // 用户登录成功时,把 token 存入 sessionStorage,如果携带 token,初始化菜单,放行
  if (window.sessionStorage.getItem('tokenStr')) {
      // 如果用户不存在
         //待首页功能部分完善后补充
  } else {
      if (to.path === '/') {
          next()
      } else {
          next('/?redirect=' + to.path)
      }
  }
})

7. Run the project

Next

B station cloud E office Vue+SpringBoot front and back end separation project - the front end dynamically obtains the menu directory

Guess you like

Origin blog.csdn.net/qq_36384657/article/details/124525482