Skip to content
生如风生如风
主页
github icon
  • 框架结构
    • 克隆运行项目
      • vue-admin-template项目改造
        • (一)分析登录请求的思路
          • (二)分析登录请求结结束
            • (三)项目改造
            • 项目改造结语

              vue-admin-template学习(一)

              author icon生如风calendar icon2021年3月20日category icon
              • Vue
              tag icon
              • Vue
              • vue-admin-template
              timer icon大约 10 分钟

              此页内容
              • 框架结构
              • 克隆运行项目
              • vue-admin-template项目改造
                • (一)分析登录请求的思路
                • (二)分析登录请求结结束
                • (三)项目改造
              • 项目改造结语

              # vue-admin-template

              在学习vue的过程中,想要获取一个vue的脚手架,便于快速进行开发,选择了vue-admin-template,将该框架进行二次开发,作为vue初学者,踩了很多坑,以此记录分析和修改。

              github:https://github.com/PanJiaChen/vue-admin-template branch: tag\3.11.0

              # 框架结构

              在这里插入图片描述 至于在src中的结构,就是基本的vue项目结构了。

              # 克隆运行项目

              1. 在IDEA中打开该项目
              2. cnpm install(首先注册好淘宝的npm,这里就不记录了)
              3. cnpm run dev
              4. 浏览器访问 http://localhost:9528/ 即可看到登录页面

              # vue-admin-template项目改造

              要想对已有的demo进行二次开发,首先的是要对demo进行了解,我认为要想比较快速的上手进行开发,拿出demo的某个请求进行分析,然后将该完整的请求过程换成自己所要开发的项目。在这里,我就拿出vue-admin-template的“登录”请求做分析。

              # (一)分析登录请求的思路

              # 请求路线

              在这里插入图片描述 既然是登录功能,那么就从登录页面开始分析。 在src\views\login\index.vue中: 除开页面基本的输入验证信息,剩下的主要方法就是登录了,如下:

              handleLogin() {
                    this.$refs.loginForm.validate(valid => {
                      if (valid) {
                        this.loading = true
                        this.$store.dispatch('Login', this.loginForm).then(() => {
                          this.loading = false
                          this.$router.push({ path: this.redirect || '/' })
                        }).catch(() => {
                          this.loading = false
                        })
                      } else {
                        console.log('error submit!!')
                        return false
                      }
                    })
                  }
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              # 登录

              (1) this.$store.dispatch('Login', this.loginForm).then(() 该请求使用$store.diepatch调取src\store\modules里的user.js的Login方法,如下:

                  // 登录
                  Login({ commit }, userInfo) {
                    const username = userInfo.username.trim()
                    return new Promise((resolve, reject) => {
                      login(username, userInfo.password).then(response => {
                        const data = response.data
                        setToken(data.token)
                        commit('SET_TOKEN', data.token)
                        resolve()
                      }).catch(error => {
                        reject(error)
                      })
                    })
                  },
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14

              (2)login(username, userInfo.password).then(response => 在new Promise中,通过login调用了src\api的login.js中的login方法 如下:

              import request from '@/utils/request'
              export function login(username, password) {
                return request({
                  url: '/user/login',
                  method: 'post',
                  data: {
                    username,
                    password
                  }
                })
              }
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11

              (3)该方法中return request,显然调用了第一行import request对应的文件中的方法。src\utils中的request.js很重要。该方法创建axios实例、 request拦截器、response 拦截器。如下:

              # 创建axios实例
              // 创建axios实例
              const service = axios.create({
                baseURL: process.env.BASE_API, // api 的 base_url
                timeout: 5000 // 请求超时时间
              })
              
              1
              2
              3
              4
              5

              在该方法中,很重要的一点是baseURL的指向。 其指向了config下的dev.env.js中的配置,如下:

              module.exports = merge(prodEnv, {
                NODE_ENV: '"development"',
                BASE_API: '"https://easy-mock.com/mock/5950a2419adc231f356a6636/vue-admin"',
              })
              
              1
              2
              3
              4

              在后面进行二次开发时,需要将BASE_API的值修改为实际项目的接口基本地址,如http://localhost:8082。

              # request拦截器
              // request拦截器
              service.interceptors.request.use(
                config => {
                  if (store.getters.token) {
                    config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
                  }
                  return config
                },
                error => {
                  // Do something with request error
                  console.log(error) // for debug
                  Promise.reject(error)
                }
              )
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14

              该拦截器主要在有request时,如果在store中存储有token则在headers中带上x-Token,实际这个拦截器中直接return config即可, 然后在登录完成后,访问其他页面的时候带上token访问。这个暂时不考虑分析。

              # response 拦截器
              service.interceptors.response.use(
                response => {
                  /**
                   * code为非20000是抛错 可结合自己业务进行修改
                   */
                  const res = response.data
                  if (res.code !== 20000) {
                    Message({
                      message: res.message,
                      type: 'error',
                      duration: 5 * 1000
                    })
                    ------省略------
                    return Promise.reject('error')
                  } else {
                    return response.data
                  }
                },
                error => {
                  console.log('err' + error) // for debug
                  Message({
                    message: error.message,
                    type: 'error',
                    duration: 5 * 1000
                  })
                  return Promise.reject(error)
                }
              )
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28

              该拦截器主要用于在请求完后,后台返回的消息进行处理。

              (4)这个”登录“请求从开始发起request到response结束,基本流程就是这样。那么,在该项目登录模块中,form数据的提交到验证在到返回数据,获取token,获取用户信息,怎么都没有看到在上面分析的方法中呢。原因是在上面的框架结构图中,使用了mock,mock的简单使用请看vue中使用mockopen in new window

              (5)在mock目录中,index.js中,定义了mock的拦截,将对“登录”请求的提交/user/login进行拦截,如下:

              import userAPI from './user'
              
              Mock.mock(/\/user\/login/, 'post', userAPI.login)
              
              1
              2
              3

              该拦截将会调用mock目录下的user.js中的login方法。如下:

              login: res => {
                  const { username } = JSON.parse(res.body)
                  const data = tokens[username]
              
                  if (data) {
                    return {
                      code: 20000,
                      data
                    }
                  }
                  return {
                    code: 60204,
                    message: 'Account and password are incorrect.'
                  }
                },
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15

              于是就会将响应数据返回,这样在src\utils\request.js中,response响应拦截就会获取到数据,并进行相应判断,按发起登录请求路线返回,在src\store\modules里的user.js登录方法中设置setToken,直至返回src\views\login\index.vue,并进行相应页面跳转。

              # (二)分析登录请求结结束

              到这里,已经将在vue-admin-template中的“登录”请求进行了分析,其他请求的分析也是这样。作为初学者,在使用这个框架时,碰到了很多问题,分析了比较久的时间,特此记录下,为了以后碰到相应的问题不在耗费太多的时间,也为了给即将学习的朋友一点思路。写得不好,感谢指出。经过分析后,后面将会进行项目的二次开发。

              # (三)项目改造

              首先,我们要改造项目,并且是“登录”功能,那么先根据上面分析的,修改项目的API接口为我们自己的,通过分析,如下:

              # dev.env.js配置

              (1)运行起来项目后,打开浏览器访问,F12打开调试控制台,选择Sources中,打开上述分析中的request.js,在如图位置打上断点,在request拦截器中,查看config中的数据

              在这里插入图片描述

              或者在console中,直接打上“config”查看

              在这里插入图片描述

              可以看到此处的baseURL的值为项目下config目录中,dev.env.js中配置的BASE_API

              在这里插入图片描述

              # 登录响应

              在上述方法中,再次在request.js的响应拦截处打个断点,查看响应的数据,如下:

              在这里插入图片描述

              在这里插入图片描述

              可以看到相应的数据,而该数据的产生,就源于我们上面说的项目mock模拟数据,mock目录下index.js拦截了url,调用了user.js中的login方法

              在这里插入图片描述

              在这里插入图片描述

              在这里插入图片描述

              于是在request.js的response拦截中获取了相应的数据。

              # 修改

              (1)将dev.env.js中的BASE_API值修改为项目(这里已我已有的后端项目接口举例,已启动后端项目)

              在这里插入图片描述

              这时来试试登录会怎么样,还是在request.js上的两个拦截器中打上断点

              在这里插入图片描述

              在这里插入图片描述

              从图中可以看出来,接口的baseURL已经变成我们想要的,但是竟然响应返回的值还是mock中的模拟数据,并且跳过断点后,仍然是登录成功进入系统。 这里还是mock拦截在操作,并不会真正访问我们自己项目的api 一种解决方法:

              在这里插入图片描述

              如上图,将mock拦截注销掉就可以了,这样user/login就不会被mock拦截,就可以访问我们的后端api。

              (2)后端登录接口:http://localhost:8082/login postman测试:

              在这里插入图片描述

              在这里插入图片描述

              在src\api\login.js中,将login方法的请求路径修改为/login(原来为/user/login)

              在这里插入图片描述

              这样,当点击登录时就可以调用我们的后端登录api接口了。 再次测试登录页面登录功能 先输入错误的密码

              报错信息图

              在这里插入图片描述

              可以看到返回的结果中就是我们后端接口的返回数据。上图中报错消息的处理后面在进行。

              输入正确的密码

              在这里插入图片描述

              可以看出返回了正确的数据,报错信息仍然和上面的报错信息图一样。因为我们还没对request.js中的response拦截器中的code进行修改,它判断出code不为20000的都是报错误消息,但是我们的后端接口200是正常,非200是异常。所以接下来,我们对拦截器进行简单修改,仅作为思路。

              (3)下面贴上修改前和修改后的

              import { Message, MessageBox } from 'element-ui'   //这个位置也注意,后面不使用MessageBox要删除,否则报错
              
              service.interceptors.response.use(
                response => {
                  /**
                   * code为非20000是抛错 可结合自己业务进行修改
                   */
                  const res = response.data
                  if (res.code !== 20000) {
                    Message({
                      message: res.message,
                      type: 'error',
                      duration: 5 * 1000
                    })
              
                    // 50008:非法的token; 50012:其他客户端登录了;  50014:Token 过期了;
                    if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
                      MessageBox.confirm(
                        '你已被登出,可以取消继续留在该页面,或者重新登录',
                        '确定登出',
                        {
                          confirmButtonText: '重新登录',
                          cancelButtonText: '取消',
                          type: 'warning'
                        }
                      ).then(() => {
                        store.dispatch('FedLogOut').then(() => {
                          location.reload() // 为了重新实例化vue-router对象 避免bug
                        })
                      })
                    }
                    return Promise.reject('error')
                  } else {
                    return response.data
                  }
                },
                error => {
                  console.log('err' + error) // for debug
                  Message({
                    message: error.message,
                    type: 'error',
                    duration: 5 * 1000
                  })
                  return Promise.reject(error)
                }
              )
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28
              29
              30
              31
              32
              33
              34
              35
              36
              37
              38
              39
              40
              41
              42
              43
              44
              45
              46

              修改后:

              import { Message } from 'element-ui'
              
              // response 拦截器
              service.interceptors.response.use(
                response => {
                  /**
                   * code为非20000是抛错 可结合自己业务进行修改
                   */
                  const res = response.data
                  console.log(res)
                  if (res.code !== 200) {
                    Message({
                      message: res.msg,
                      type: 'error',
                      duration: 5 * 1000
                    })
              
                    // // 50008:非法的token; 50012:其他客户端登录了;  50014:Token 过期了;
                    // if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
                    //   MessageBox.confirm(
                    //     '你已被登出,可以取消继续留在该页面,或者重新登录',
                    //     '确定登出',
                    //     {
                    //       confirmButtonText: '重新登录',
                    //       cancelButtonText: '取消',
                    //       type: 'warning'
                    //     }
                    //   ).then(() => {
                    //     store.dispatch('FedLogOut').then(() => {
                    //       location.reload() // 为了重新实例化vue-router对象 避免bug
                    //     })
                    //   })
                    // }
                    return Promise.reject('error')
                  } else {
                    return response.data
                  }
                },
                error => {
                  console.log('err' + error) // for debug
                  Message({
                    message: error.msg,
                    type: 'error',
                    duration: 5 * 1000
                  })
                  return Promise.reject(error)
                }
              )
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28
              29
              30
              31
              32
              33
              34
              35
              36
              37
              38
              39
              40
              41
              42
              43
              44
              45
              46
              47
              48

              在这里插入图片描述

              再次登录,发现打印的登录成功,但是会报错,那是因为登录成功后触发了获取用户信息的方法,获取出错。后端api接口在登录成功时返回了用户的信息。要设置用户信息等,可以在下面的方面内设置,包括token,关于获取用户信息就不说了。

              # 项目改造结语

              关于对vue-admin-template的分析和改造就到此了,通过分析一个登录请求到响应,了解该项目的流程及功能点。至于其他的,可以参考该登录请求作为了解。 作为初学者,很多前端的知识都没有掌握,见谅,如有错误请指出,以期进步,感谢!

              默认页脚
              Copyright © 2026 生如风