当前位置:   article > 正文

Vue3+SpringBoot实现文件上传详细教程_vue3 文件上传

vue3 文件上传

      文件上传的功能实现是我们做Web应用时候最为常见的应用场景,比如:实现头像的上传,Excel文件数据的导入等功能,都需要我们先实现文件的上传,然后再做图片的裁剪,excel数据的解析入库等后续操作。

    今天通过这篇文章,我们就来一起学习一下如何在Vue3+SpringBoot中实现文件的上传,这篇文章主要使用图片上传进行讲解。

    主要逻辑为:本案例实现商品信息的上传功能,包含商品的文字信息及商品图片

如下图显示:

点击“新增”

具体核心代码,如下

1. SpringBoot 中核心代码

  1. @RestController
  2. @RequestMapping("/bg/product")
  3. public class ProductController {
  4. @Autowired
  5. private ProductService productService;
  6. @RequestMapping("/queryall")
  7. private Message queryAll(){
  8. return productService.queryall();
  9. }
  10. @RequestMapping("/save")
  11. private Message addProduct(@RequestBody Product product){
  12. return productService.save(product);
  13. }
  14. @RequestMapping("/upload")
  15. private String ImageUpload(@RequestParam MultipartFile file, HttpServletRequest request)throws Exception{
  16. // 综合考虑:两个位置都上传文件
  17. //2. 指定文件上传的目录(target/classes/xxx)
  18. //2.1 文件存储到此位置,可以提供页面的访问(当前target中的内容不会打包上传到服务器上)
  19. String path_target = ClassUtils.getDefaultClassLoader().getResource("static").getPath()+"/upload/";
  20. //2. 指定文件上传的目录(当前项目的src/main/resources/static/upload 下)
  21. //2.1 文件存储到此位置,可以保存上传的图片,并打包上传到服务器上(在项目中执行 install 就可以生成target中的所有内容)
  22. String path = System.getProperty("user.dir")+"/src/main/resources/static/upload";
  23. //3. 判断此目录是否存在
  24. File fileDir_target = new File(path_target);
  25. if(!fileDir_target.exists()){
  26. fileDir_target.mkdirs();
  27. }
  28. File fileDir = new File(path);
  29. if(!fileDir.exists()){
  30. fileDir.mkdirs();
  31. }
  32. //4. 生成新的名字
  33. String oldName = file.getOriginalFilename();
  34. String newName = UUID.randomUUID().toString().replaceAll("-","")+oldName.substring(oldName.lastIndexOf("."),oldName.length());
  35. //5. 指定生成的文件
  36. File file_target = new File(fileDir_target.getAbsolutePath()+File.separator+newName);
  37. File file_1 = new File(fileDir.getAbsolutePath()+File.separator+newName);
  38. //6. 文件的生成
  39. file.transferTo(file_1);
  40. FileCopyUtils.copy(file_1,file_target);
  41. //7. 生成http的访问路径
  42. String httpPath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+"/"
  43. + request.getContextPath()+"upload/"+newName;
  44. System.out.println("path:"+path);
  45. System.out.println("path_target:"+path_target);
  46. System.out.println("httpPath:"+httpPath);
  47. return httpPath;
  48. }
  49. }

2. vue中核心代码

    流程为:先将图片上传到Springboot服务器上,服务器返回给图片的http访问地址,将http访问地址与商品的信息再一起上传到服务器上

  1. <template>
  2. <el-breadcrumb separator="/" style="margin-bottom: 20px;">
  3. <el-breadcrumb-item>系统管理</el-breadcrumb-item>
  4. <el-breadcrumb-item>商品管理</el-breadcrumb-item>
  5. </el-breadcrumb>
  6. <div>
  7. <el-text class="mx-1">商品名</el-text>
  8. <el-input v-model="input" style="width: 200px; margin-right: 10px;" />
  9. <el-button type="primary">搜索</el-button>
  10. <el-button type="warning" @click="dialogVisible = true">新增</el-button>
  11. </div>
  12. <el-table :data="tableData" style="width: 100%;margin-top: 20px;">
  13. <el-table-column type="index" label="序号" width="80" />
  14. <el-table-column prop="productName" label="名称" width="120" />
  15. <el-table-column prop="categoryName" label="类型" width="120" />
  16. <el-table-column prop="productPath" label="图片" width="120" >
  17. <template #default="scope">
  18. <img :src="scope.row.productPath" min-width="50" height="50"/>
  19. </template>
  20. </el-table-column>
  21. <el-table-column prop="costPrice" label="进价" width="120" />
  22. <el-table-column prop="generalPrice" label="普通价" width="120" />
  23. <el-table-column prop="superPrice" label="会员价" width="120" />
  24. <el-table-column prop="stock" label="库存" width="120" />
  25. <el-table-column prop="address" label="操作" >
  26. <template #default="scope">
  27. <el-button
  28. size="mini"
  29. @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
  30. <el-button
  31. size="mini"
  32. @click="handleDelete(scope.$index, scope.row)">删除</el-button>
  33. </template>
  34. </el-table-column>
  35. </el-table>
  36. <!--商品新增的对话框-->
  37. <el-dialog
  38. v-model="dialogVisible"
  39. title="添加商品"
  40. width="30%"
  41. >
  42. <el-form-item label="商品名">
  43. <el-input v-model="product.productName" />
  44. </el-form-item>
  45. <el-form-item label="商品描述">
  46. <el-input v-model="product.productDescription" type="textarea"/>
  47. </el-form-item>
  48. <el-form-item label="商品类型">
  49. <el-select v-model="product.categoryId" placeholder="请选择类别">
  50. <el-option
  51. v-for="item in categoryData"
  52. :key="item.id"
  53. :label="item.categoryName"
  54. :value="item.id"
  55. />
  56. </el-select>
  57. </el-form-item>
  58. <el-form-item label="成本价格">
  59. <el-input v-model="product.costPrice" />
  60. </el-form-item>
  61. <el-form-item label="普通价格">
  62. <el-input v-model="product.generalPrice" />
  63. </el-form-item>
  64. <el-form-item label="会员价格">
  65. <el-input v-model="product.superPrice" />
  66. </el-form-item>
  67. <el-form-item label="库存">
  68. <el-input v-model="product.stock" />
  69. </el-form-item>
  70. <el-form-item label="图片">
  71. <input type="file" name="myfile" @change="handleFileUpload"/>
  72. </el-form-item>
  73. <template #footer>
  74. <span class="dialog-footer">
  75. <el-button @click="dialogVisible = false">取消</el-button>
  76. <el-button type="primary" @click="saveProduct">
  77. 确定
  78. </el-button>
  79. </span>
  80. </template>
  81. </el-dialog>
  82. </template>
  83. <script setup>
  84. import {reactive, ref} from 'vue'
  85. import http from '../api/request'
  86. import { ElMessage } from 'element-plus'
  87. const dialogVisible = ref(false)
  88. const categoryData = ref([])
  89. const tableData = ref([])
  90. const product = reactive({
  91. productName:'',
  92. productDescription: '',
  93. categoryId: null,
  94. generalPrice: null,
  95. superPrice: null,
  96. costPrice: null,
  97. stock: null,
  98. productPath: null,
  99. myfile: null
  100. })
  101. //-获取所有商品信息
  102. function getProductData(){
  103. http.post('/bg/product/queryall')
  104. .then(response=>{
  105. return response.data.data
  106. }).then(data=>{
  107. console.log(data)
  108. tableData.value = data
  109. })
  110. }
  111. getProductData()
  112. //-获取商品分类信息
  113. function getCategoryData(){
  114. http.post('/bg/category/queryall')
  115. .then(response=>{
  116. return response.data.data
  117. }).then(data=>{
  118. console.log(data)
  119. categoryData.value = data
  120. })
  121. }
  122. getCategoryData()
  123. //-图片上传
  124. const handleFileUpload =(event)=>{
  125. const file = event.target.files[0];
  126. let formData = new FormData();
  127. formData.append('file',file);
  128. http.post('/bg/product/upload',formData,{
  129. headers: {
  130. 'Content-Type':'multipart/form-data'
  131. }
  132. }).then(response=>{
  133. product.productPath = response.data
  134. })
  135. }
  136. //-商品上传
  137. const saveProduct =()=>{
  138. //-:对话框的关闭
  139. dialogVisible.value = false
  140. http.post('/bg/product/save',{
  141. productName: product.productName,
  142. productDescription: product.productDescription,
  143. categoryId: product.categoryId,
  144. generalPrice: product.generalPrice,
  145. superPrice: product.superPrice,
  146. costPrice: product.costPrice,
  147. stock: product.stock,
  148. productPath: product.productPath
  149. }).then(function(response){
  150. return response.data.data
  151. }).then((data)=>{
  152. ElMessage.success('添加成功');
  153. //-:查询商品列表
  154. getProductData()
  155. })
  156. }
  157. </script>
  158. <style>
  159. </style>

到此,此案例整理完毕!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/384010
推荐阅读