• vue3加axios配合element-plus实现图片等文件本地上传,并获取服务器返回的真实地址数据,前端写法


    小白写法嘿嘿

    开发工具和关键词

    开发工具: vscode

    关键词:vue3、element-plus、axios

    后端

    后端业务逻辑处理使用的是unicloud的云函数,大家可以看我上一篇文章。

    思路

    1、禁止element-plus的el-upload组件自动上传,变成手动上传,提交表单时候统一处理上传文件

    2、此时el-upload组件中的file文件保存到了v-model:file-list="fileList"的fileList的变量中,数据类型类型是file对象的数组

    3、提交表单,循环fileList数组,将file数据类型的文件转化成base64编码

    4、将子元素为base64编码数据的图片数组依次上传到服务器,并依次获取一个真实的服务器图片地址,并将这些真实地址保存到pictureslist数组

    4、后面可以根据自己的代码逻辑处理真实地址的图片数组pictureslist,如:商品多张图片可以将数组转为json格式,保存到数据表中的某一个pictures字段中,后续展示商品直接读取即可

    注意:这里不考虑文件上传中断和大文件的情况。

    完整代码

     addproduct.vue

    1. <template>
    2. <div style="width: 80%;">
    3. <el-form :model="form" label-width="auto" style="max-width: 600px">
    4. <el-form-item label="标题">
    5. <el-input v-model="form.bt" />
    6. el-form-item>
    7. <el-upload v-model:file-list="fileList" action="ok" :auto-upload="false" list-type="picture-card"
    8. :on-preview="handlePictureCardPreview" :on-remove="handleRemove" multiple>
    9. <el-icon>
    10. 添加
    11. <Plus />
    12. el-icon>
    13. el-upload>
    14. <el-dialog v-model="dialogVisible">
    15. <img w-full :src="dialogImageUrl" alt="Preview Image" />
    16. el-dialog>
    17. <el-form-item>
    18. <el-button type="primary" @click="onSubmit">新增el-button>
    19. el-form-item>
    20. el-form>
    21. div>
    22. template>
    23. <script>
    24. import { ref, reactive } from 'vue'
    25. import axios from 'axios'
    26. const dialogImageUrl = ref('')
    27. const dialogVisible = ref(false)
    28. //这里用了响应式数据
    29. var form = reactive({
    30. bt: '',
    31. //tp是保存了真实图片地址后的json数组
    32. tp: '',
    33. })
    34. export default {
    35. name: 'HomeView',
    36. data() {
    37. return {
    38. form,
    39. dialogImageUrl,
    40. dialogVisible,
    41. fileList: [],
    42. zh: sessionStorage.getItem('zh')
    43. }
    44. },
    45. methods: {
    46. async onSubmit() {
    47. var that = this
    48. console.log('submit!')
    49. console.log(this.form);
    50. if (this.fileList.length == 0) {
    51. return ElMessage({
    52. message: '请先上传图片!',
    53. grouping: true,
    54. type: 'warning',
    55. });
    56. }
    57. await this.upaction(); // 等待上传图片完成
    58. console.log("我的上传图片的真实路径", this.fileList);
    59. var pictureslist = []
    60. for (let i = 0; i < this.fileList.length; i++) {
    61. pictureslist.push(this.fileList[i].url)
    62. }
    63. // 将合并后的数组转换为 JSON 字符串
    64. var jsonString = JSON.stringify(pictureslist);
    65. console.log("转换后的 JSON 字符串", jsonString);
    66. // 将转换后的 JSON 字符串赋值给 this.form.tp
    67. this.form.tp = jsonString;
    68. console.log("待上传表单数据", form);
    69. this.form.zh = this.zh
    70. // 将表单数据上传服务器
    71. const res = await axios.post(
    72. "/api/addproduct", // 请求后端的 URL
    73. that.form,
    74. {
    75. headers: {
    76. "Content-Type": "application/json;charset=utf-8",
    77. "Access-Control-Allow-Origin": "*", // 允许所有域名访问,或者设置为特定的域名
    78. "Access-Control-Allow-Methods": "GET, POST, OPTIONS", // 允许的请求方法
    79. "Access-Control-Allow-Headers": "Content-Type", // 允许的请求头
    80. },
    81. }
    82. );
    83. console.log("请求后", res);
    84. loadingInstance.close()
    85. ElMessage({
    86. message: '上传成功!',
    87. grouping: true,
    88. type: 'success',
    89. })
    90. },
    91. handlePictureCardPreview(uploadFile) {
    92. console.log(uploadFile);
    93. this.dialogImageUrl = uploadFile.url
    94. this.dialogVisible = true
    95. },
    96. handleRemove(file, fileList) {
    97. console.log(file)
    98. console.log(fileList)
    99. },
    100. // 依次上传图片
    101. async upaction() {
    102. var that = this
    103. for (let i = 0; i < this.fileList.length; i++) {
    104. var src = await this.uploadFile(this.fileList[i]);
    105. this.fileList[i].url = src
    106. }
    107. },
    108. //保存至服务器后返回真实图片路径地址
    109. async uploadFile(file) {
    110. console.log("uploadFile中,未编码url为", file.url);
    111. const newbasesrc = await this.getdata(file);
    112. console.log("编码url后", newbasesrc);
    113. const res = await axios.post(
    114. "/api/upload", // 请求后端的 URL
    115. { file: newbasesrc },
    116. {
    117. headers: {
    118. "Content-Type": "multipart/form-data;charset=utf-8",
    119. "Access-Control-Allow-Origin": "*", // 允许所有域名访问,或者设置为特定的域名
    120. "Access-Control-Allow-Methods": "GET, POST, OPTIONS", // 允许的请求方法
    121. "Access-Control-Allow-Headers": "Content-Type", // 允许的请求头
    122. },
    123. }
    124. );
    125. console.log(res);
    126. return res.data.fileUrl;
    127. },
    128. //以下两个自定义函数是为了将input直接获取的file对象转成base64编码格式
    129. async getdata(file) {
    130. // 使用 FileReader 将文件转换为 base64 编码字符串
    131. console.log("getdata函数中,准备转化", file);
    132. const base64String = await this.readFileAsBase64(file);
    133. console.log("获得编码", base64String);
    134. return base64String;
    135. },
    136. readFileAsBase64(file) {
    137. return new Promise((resolve, reject) => {
    138. const reader = new FileReader();
    139. reader.onload = (event) => {
    140. // 将文件转换为 base64 编码
    141. const base64String = event.target.result;
    142. resolve(base64String);
    143. };
    144. reader.onerror = reject;
    145. // 读取文件内容并转换为 base64 编码字符串
    146. reader.readAsDataURL(file.raw);
    147. });
    148. },
    149. }
    150. }
    151. script>

     如果对您有所帮助,给个小赞赞吧!🌹

  • 相关阅读:
    参编三大金融国标,奇富科技以技术促行业规范化演进
    绿色工厂申报流程
    leetcode 16.01. 交换数字(不使用临时变量交换2个数的值)
    FPGA UDP RGMII 千兆以太网(2)IDDR
    好客租房120-在脚手架中使用sass
    java---数位dp---计数问题(每日一道算法2022.10.21)
    7-25 念数字
    CSS 中::after的妙用(实现在margin中显示内容)
    【Vue】内置指令
    Retrofit原理解析(二)
  • 原文地址:https://blog.csdn.net/weixin_57177381/article/details/139398709