常规的Promise上传

image.png
image.png

  1. <template>
  2. <div>
  3. <label for="upload" class="choose-img" :class="{'uploading-grey': isUploading}">选择图片上传</label>
  4. <!-- input multiple 属性,保证了input支持多选-->
  5. <!-- accept="image/*" 可以用来限制选中的文件类型为图片类型-->
  6. <input type="file" multiple id="upload"
  7. accept="image/*"
  8. @change="onChange"
  9. :disabled="isUploading"
  10. ref="file"
  11. style="display: none">
  12. <p class="tip">提示: 一次可选择多张图片,最多不超过9张(单张图片大小 &lt; 1M)</p>
  13. </div>
  14. </template>
  15. <script>
  16. // 阿里云存储配套的依赖
  17. import OSS from 'ali-oss'
  18. export default{
  19. data() {
  20. return {
  21. // 传入阿里云存储的信息,生成连接用的信息对象
  22. clinet: new OSS({
  23. region: 'oss-cn-beijing',
  24. bucket: 'imooc-es',
  25. accessKeyId: '',
  26. accessKeySecret: ''
  27. }),
  28. // 专门存储,图片上传成功后的url地址
  29. imgList: [],
  30. // 判断图片是否处于上传中
  31. isUploading: false
  32. }
  33. },
  34. methods: {
  35. // 选取文件以及校验的过程
  36. onChange() {
  37. const newFiles = this.$refs?.file?.files
  38. // 校验选择图片的个数
  39. if (newFiles.length > 9) {
  40. alert('最多可选9张图片')
  41. return false
  42. }
  43. const files = []
  44. // 校验图片大小
  45. for (const file of newFiles) {
  46. // 将文件大小的单位转化成M
  47. const size = file.size / 1024 / 1024
  48. if (size > 1) {
  49. alert('请选择1M以内的图片')
  50. return false
  51. }
  52. files.push(file)
  53. }
  54. this.uploadFilesByOss(files)
  55. },
  56. // 处理文件上传到阿里云存储的过程
  57. uploadFilesByOss(files) {
  58. // 上传图片按钮置灰
  59. this.isUploading = true
  60. const uploadRequesst = []
  61. for(const file of files){
  62. uploadRequesst.push(new Promise((resolve, reject) =>{
  63. this.clinet.put(`${Math.random()}-${file.name}`, file).then(res => {
  64. resolve(res.url)
  65. }).catch(err => {
  66. console.log(err)
  67. reject(err)
  68. });
  69. }))
  70. }
  71. // 使用 Promise.allSettled 比 Promise.all 的好处就是
  72. // 即使有一个图片上传请求失败,不会影响其他图片上传请求的执行
  73. Promise.allSettled(uploadRequesst).then(res => {
  74. const imgs = []
  75. for (const item of res) {
  76. if(item.status === 'fulfilled'){
  77. imgs.push(item.value)
  78. }
  79. }
  80. this.imgList = imgs
  81. // 上传图片按钮恢复
  82. this.isUploading = false
  83. });
  84. }
  85. }
  86. }
  87. </script>
  88. <style scoped>
  89. .choose-img{
  90. display: block;
  91. width: 150px;
  92. height: 50px;
  93. line-height: 50px;
  94. text-align: center;
  95. background-color: #42b983;
  96. color: #fff;
  97. border-radius: 5px;
  98. cursor: pointer;
  99. }
  100. /*表示上传图片按钮置灰*/
  101. .uploading-grey{
  102. background-color: #ccc;
  103. }
  104. .tip{
  105. color: #ccc;
  106. }
  107. </style>

Promise.allSettled() 上传图片后的返回值
image.png

更加优雅的异步操作

主要是针对 uploadFilesByOss() 方法的优化,使用 async/ await 对,阿里云存储中,图片上传过程的代码优化
去除了原来 Promise 中的回调操作

async uploadFilesByOss2(files) {
  // 上传图片按钮置灰
  this.isUploading = true
  const imgs = []
  for (const file of files) {
    const res = await this.clinet.put(`${Math.random()}-${file.name}`, file)
    imgs.push(res.url)
  }
  this.imgList = imgs
  this.isUploading = false
}