【springboot+vue项目(八)】VUE 与后端数据交互的3种方式

一、准备工作

(一)代理跨域

//vue.config.js 
const { defineConfig } = require('@vue/cli-service')
module.exports = {
  //  关闭eslint
    lintOnSave: false,
    // 代理跨域
    devServer: {
      proxy: {
        '/api': {
          target: 'http://localhost:8989',
          pathRewrite: { '^/api': '' }
        }
      }
    }
  }

(二)安装axios

npm install axios

 二、在组件内直接通过axios发请求(不常用

<template>
  <div class="table-container">
    <el-table :data="uploadLogList" border style="width: 100%" header-align="center">
      <el-table-column type="index" label="序号" width="120" align="center">
      </el-table-column>
      <el-table-column prop="filename" label="文件名" width="350" align="center">
        <template slot-scope="scope">
          {{ scope.row.filename }}
        </template>
      </el-table-column>
      <el-table-column prop="filepath" label="文件路径" width="480" align="center">
        <template slot-scope="scope">
          {{ scope.row.filepath }}
        </template>
      </el-table-column>
      <el-table-column prop="uploadtime" label="上传时间" width="450" align="center">
        <template slot-scope="scope">
          {{ scope.row.uploadtime }}
        </template>
      </el-table-column>
      <el-table-column prop="status" label="文件状态" align="center">
        <template slot-scope="scope">
          {{ scope.row.status }}
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      uploadLogList: [], // 初始化为空数组
    };
  },
  created() {
    this.fetchData(); // 在created钩子函数中调用fetchData方法
  },
  methods: {
    fetchData() {
      axios.get('/dev-upload/uploadFiles/listAll')
        .then(response => {
          if (response.data.code === 200) { // 检查返回的状态码
            this.uploadLogList = response.data.data;
          } else {
            console.error('请求失败:', response.data.msg);
          }
        })
        .catch(error => {
          console.error(error);
        });
    },
  },
};
</script>

<style scoped>
.table-container {
  margin-left: 100px;
  margin-right: 100px;
  margin-top: 50px;
}

.el-table th {
  text-align: center;
}
</style>

        Vue组件的script部分定义了一个名为fetchData的方法,使用axios发送GET请求来获取服务器上的数据。

        该方法在组件创建时调用,通过将数据存储在uploadLogList数组中来更新组件的状态。

代码执行的流程如下:

  1. 首先,在组件创建时,created钩子函数被调用。

  2. 在created钩子函数中,调用了fetchData方法来获取数据。

  3. fetchData方法使用axios发送GET请求,请求服务器上的'/dev-upload/uploadFiles/listAll'资源。

  4. 如果请求成功,服务器将返回一个状态码和数据。在这个组件中,检查状态码是否为200。

  5. 如果状态码为200,则将数据存储在uploadLogList数组中。这将自动更新组件的状态,并重新渲染组件以显示这些数据。

  6. 如果状态码不为200,则在控制台中输出错误信息。

  7. 如果请求失败,则将错误信息打印到控制台中。

  8. 组件完成渲染,此时表格应该显示从服务器获取的数据。

总的来说,该组件通过fetchData方法获取数据,使用axios发送GET请求来请求服务器上的数据。如果请求成功,则将数据存储在uploadLogList数组中,如果请求失败,则在控制台中输出错误信息。在组件创建时和每次请求数据时都会调用fetchData方法,以确保在组件渲染之前已获取到数据。

二、通过API全局封装(常用,大小项目都可

 (一)axios的二次封装

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// 创建一个axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,  // 接口的基础路径
  timeout: 5000 // 请求超时时间
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 在请求发送前做一些处理
    if (store.getters.token) {
      // 如果有token就在请求头中加上token
      config.headers['token'] = getToken()
    }
    return config
  },
  error => {
    // 对请求错误做些什么
    console.log(error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    // 对响应数据做一些处理,这里只返回响应数据中的data部分
    const res = response.data

    // 如果自定义的响应码不是20000,就判断为错误
    if (res.code !== 20000 && res.code !== 200) {
      // 在页面上显示错误信息
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // 重新登录
        MessageBox.confirm('您已经登出,您可以取消以留在此页面,或重新登录', '确认登出', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      // 返回一个被拒绝的Promise对象,用来表示错误
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      // 如果没有错误,就返回响应数据中的data部分
      return res
    }
  },
  error => {
    // 对响应错误做些什么
    console.log('err' + error)
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

(二)API接口统一管理 

// api/upload.js
// 当前这个模块:api进行统一管理
import request from '@/api/request/request-upload'

// 上传文件
//普通函数形式 export default { methods: { listAllInfo() { axios.get('/uploadlogs/listAll').then(response => { console.log(response.data); }).catch(error => { console.error(error); }); } } }

export const uploadFiles = (formData) => request({
  url: '/uploadExcel',
  method: 'post',
  data: formData,
  headers: {
    'Content-Type': 'multipart/form-data'
  }
});

// 获取上传文件日志接口
export const reqListAllInfo = () =>request({
  url:'/uploadFiles/listAll',
  method: 'get'
});

(三)接口对外统一暴露

// /api/index.js
// 将模块的接口函数统一引入
import * as table from './table';
import * as upload from './upload';
import * as user from './user';


// 统一对外暴露
export default {
    table,
    upload,
    user
}

(四) 全局封装API

// main.js 全局封装API

import API from '@/api';

Vue.prototype.$API= API;

(五)组件调用

<template>
  <div  class="table-container">
    <el-table :data="uploadLogList" border style="width: 100%" header-align="center">
      <el-table-column type="index" label="序号" width="120" align="center">
      </el-table-column>
      <el-table-column prop="filename" label="文件名" width="350" align="center">
      </el-table-column>
      <el-table-column prop="filepath" label="文件路径" width="480" align="center">
      </el-table-column>
      <el-table-column prop="uploadtime" label="上传时间" width="450" align="center">
      </el-table-column>
      <el-table-column prop="status" label="文件状态" align="center">
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
  export default {
    name: '',
    data () {
      return {
        uploadLogList: [], // 初始化为空数组
      }
    },
    computed: {},// 计算属性
    mounted() {
      // 获取列表数据方法
      this.getPageList(); 
    },// dom元素创建之后执行
    methods: {
      async getPageList(){
        let result = await this.$API.upload.reqListAllInfo();
        if (result.code == 200) {
        this.uploadLogList = result.data;
      }
   }

    },// 定义方法的地方
  }
</script>

<style scoped>
.table-container {
  margin-left: 100px;
  margin-right: 100px;
  margin-top: 50px;
}

.el-table th {
  text-align: center;
}
</style>

        Vue组件的script定义了一个名为getPageList的异步方法,使用$API.upload.reqListAllInfo方法来获取服务器上的数据。

        该方法在组件挂载后调用,通过将数据存储在uploadLogList数组中来更新组件的状态。

代码执行的流程如下:

        1、首先,在组件挂载后,mounted钩子函数被调用。

        2、在mounted钩子函数中,调用了getPageList方法来获取数据。

        3、getPageList方法使用await关键字等待$API.upload.reqListAllInfo方法返回的结果。        

       4、$API.upload.reqListAllInfo方法将发送一个GET请求,请求服务器上的数据。

       5、 如果请求成功,服务器将返回一个状态码和数据。在这个组件中,检查状态码是否为200。

       6、如果状态码为200,则将数据存储在uploadLogList数组中。这将自动更新组件的状态,并重新渲染组件以显示这些数据。

        7、如果状态码不为200,则在控制台中输出错误信息。

        8、如果请求失败,则将错误信息打印到控制台中。

        9、组件完成渲染,此时表格应该显示从服务器获取的数据。

        总的来说,该组件通过getPageList方法获取数据,使用$API.upload.reqListAllInfo方法 来请求服务器上的数据。如果请求成功,则将数据存储在uploadLogList数组中,如果 请求失败,则在控制台中输出错误信息。在组件挂载后调用getPageList方法,以确保在组件渲染之前已获取到数据。

三、通过VUEX状态管理(适合大型项目

开发代码的顺序:(小白一眼懂)

     组件UploadLog.vue-->store/uploadfile.js-->store/index.js -->api/upload.js

(一)axios的二次封装(和上述一致

(二)API接口统一管理 (和上述一致

(三)在项目中安装 Vuex

npm install vuex

(四)main.js引入总仓库并注册仓库

//引入总仓库并注册 
import store from './store'

new Vue({
  // 注册仓库:组件实例的身上会多一个属性$store属性
  store, 
  render: h => h(App)
}).$mount('#app')

(五)引入Vuex和小仓库

        在src下store文件夹index.js 中引入Vuex和小仓库(在src下store文件夹下新建use文件夹-index.js 用来存储user的状态数据)

//index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

// 引入小仓库
import user from './uploadfile'


// 对外暴露Store类的一个实例

export default new Vuex.Store ({
    // 实现Vuex仓库模块式开发存储数据
    modules:{
       uploadfile,    
    }
 
});

(六)新建模块小仓库

//uploadfile.js

import { reqListAllInfo } from '@/api/upload';

const state = {
  uploadLogList: [],
};

const mutations = {
  SET_UPLOAD_LOG_LIST(state, uploadLogList) {
    state.uploadLogList = uploadLogList;
  },
};

const actions = {
  async fetchUploadLogList({ commit }) {
    try {
      const result = await reqListAllInfo();
      if (result.code === 200) {
        commit("SET_UPLOAD_LOG_LIST", result.data);
      } else {
        throw new Error('fail');
      }
    } catch (error) {
      console.error(error);
    }
  },
};

const getters = {};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters,
};

 (七)组件调用

//UploadLog.vue
<template>
  <div  class="table-container">
    <el-table :data="uploadLogList" border style="width: 100%" header-align="center">
      <el-table-column type="index" label="序号" width="120" align="center">
      </el-table-column>
      <el-table-column prop="filename" label="文件名" width="350" align="center">
      </el-table-column>
      <el-table-column prop="filepath" label="文件路径" width="480" align="center">
      </el-table-column>
      <el-table-column prop="uploadtime" label="上传时间" width="450" align="center">
      </el-table-column>
      <el-table-column prop="status" label="文件状态" align="center">
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    // 另一种写法 ...mapState({  uploadLogList: (state) => state.uploadfile.uploadLogList })
    ...mapState('uploadfile', ['uploadLogList'])
  },
  mounted() {
    this.$store.dispatch('uploadfile/fetchUploadLogList');
  }
};
</script>

<style scoped>
.table-container {
  margin-left: 100px;
  margin-right: 100px;
  margin-top: 50px;
}

.el-table th {
  text-align: center;
}
</style>

  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值