欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue-element-admin与后端交互流程(补)

程序员文章站 2022-06-06 20:25:07
...

有些朋友说,一个交互过程东一下,西一下的,不知所以然,所以在此补一下vue-element-admin的整体框架结构,并细说一下交互的过程

一:首先是整体框架结构:

├── build                      // 构建相关(build.js/webpack等)
├── config                     // 配置相关 (代理环境配置/local端口配置等等)
├── dist                       //打包后的dist文件 (供发布到线上使用)
├── src                        // 源代码
│   ├── api                    // 所有请求
│   ├── service                //请求(和api相同,我习惯写到这里,更语义化)
│   ├── assets                 // 主题 字体等静态资源
│   ├── components             // 全局公用组件
│   ├── directive              // 全局指令
│   ├── filters                // 全局 filter
│   ├── icons                  // 项目所有 svg icons
│   ├── lang                   // 国际化 language
│   ├── mock                   // 项目mock 模拟数据
│   ├── router                 // 路由
│   ├── store                  // 全局 store管理
│   ├── styles                 // 全局样式
│   ├── utils                  // 全局公用方法 (可以封装一下cookie或者request的一些函数)
│   ├── vendor                 // 公用vendor
│   ├── views                  // views 所有页面 (一般要和api/service起名相同,方便迭代)
│   ├── App.vue                // 入口页面
│   ├── main.js                // 入口文件 加载组件 初始化等
│   └── permission.js          // 权限管理 (根据权限配置路由)
├── static                     // 第三方不打包资源
│   └── Tinymce                // 富文本
├── .babelrc                   // babel-loader 配置
├── .eslintrc.js               // eslint 配置项
├── .gitignore                 // git 忽略项
├── .travis.yml                // 自动化CI配置
├── favicon.ico                // favicon图标
├── index.html                 // html模板
└── package.json               // package.json

ok,我想框架结构上在上面已经写的很详细了,下面说一下一个交互的具体实现流程吧

1.首先是在view页面进行交互提交,这个就不多说了,页面级的

2.点击提交后会调用api/service里的请求函数

3.请求函数会调用之前封装好的axsio请求函数

4.接收后端返回的response然后进行view的data渲染

下面附代码细说一下

// views/ceshi
<button @click="ceshia">举例测试</button>

import { ceshi } from '@service/ceshi'
export default {
  data() {
    list: '',
    tokon: 'suibian'
  },
  methods: {
    ceshia() {
      ceshi(this.tokon).then(res => {
        this.list = res.data.list
      })
    }
  }
}

其中的from的ceshi.js函数里如下写

import request from '@utils/request'  //引入request中封装的请求函数,包括请求拦截器,response,error等操作

export function ceshi(data) {
  return ruquest ({
    url: 'i/suibian/suibian/suibian',
    method: 'post',
    data
  })
}

之后是调用utils/request,里面这样写

import store form '@store' //引入vuex,因为需要在这里根据角色获取路由id,并在store中进行更改

// create an axios instance
const service = axios.create({
  baseURL: process.env.BASE_API, // api的base_url
  timeout: 5000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // Do something before request is sent
    return config
  },
  error => {
    // Do something with request error
    console.log(error) // for debug
    Promise.reject(error)
  }
)

// respone interceptor
service.interceptors.response.use(
  // response => response,
  /**
   * 下面的注释为通过在response里,自定义code来标示请求状态
   * 当code返回如下情况则说明权限有问题,登出并返回到登录页
   * 如想通过xmlhttprequest来状态码标识 逻辑可写在下面error中
   * 以下代码均为样例,请结合自生需求加以修改,若不需要,则可删除
   */
  response => {
    const res = response.data
    if (res.error_code !== 0) {
      Message({
        message: res.error_msg,
        type: 'error',
        duration: 2 * 1000
      })
      // 50008:非法的token; 50012:其他客户端登录了;  50014:Token 过期了;
      if (res.error_code === 10009) {
        // 请自行在引入 MessageBox
        // import { Message, MessageBox } from 'element-ui'
        MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          store.dispatch('FedLogOut').then(() => {
            location.reload() // 为了重新实例化vue-router对象 避免bug
          })
        })
      }
      return Promise.reject(response.data)
    } else {
      return response.data
    }
  },
  error => {
    const reg = new RegExp(/504|503|500|400/)
    if (reg.test(error.message) || error.message === 'Network Error') {
      Message({
        message: '网络断了,请检查网络!',
        type: 'error',
        duration: 5 * 1000
      })
    } else {
      Message({
        message: error.message,
        type: 'error',
        duration: 5 * 1000
      })
    }
    return Promise.reject(error)
  }
)