登录
原创

vue-oss阿里云上传图片

发布于 2021-11-12 阅读 618
  • 前端
  • Vue.js
原创

先搭建vue框架,配置路由、添加图片上传页面链接、添加图片上传页面,

image.png

然后进行以下操作:

1. 首先到阿里云上面开通oss服务

2. 安装ali-oss包,vue项目根目录下执行命令- - -‘npm install ali-oss --save’

安装ali-oss包,并记录到package.json文件- - -开发环境(devDependencies)和生产环境(dependencies)都需要安装这个依赖包 (–save -dev的表示只有开发环境安装依赖包)

3. 安装完成后,script中导入ali-oss包- - -“import OSS from ‘ali-oss’”

4. data(){}返回数据中创建oss对象,使用oss对象的put()方法上传文件:

注意:保管好自己的AccessKey账户信息,不要给别人看,避免信息泄露

创建oss对象:

data () {
    return {
      // 创建oss对象
      client: new OSS({
        region: '在oss上开通的信息',
        bucket: '阿里云oss创建的存储空间名',
        accessKeyId: '阿里云上查看自己的accessKeyId',
        accessKeySecret: '阿里云上查看自己的accessKeySecret'
      })
    }
  },

这几个属性名称是固定的,注意不要写错了

put()方法上传文件:

// put('上传的文件的名称', 上传的文件) 注意文件名称要是唯一的,所以这里使用了随机函数
this.client.put(`${Math.random()}-${file.name}`, file)

region值:

region值.png

查看AccessKey管理控制位置:

image.png

5. 注意要到阿里云上进行配置跨域设置:

防止上传文件失败,具体配置可根据自己需求,
没有进行跨域配置会报错如下:

上传失败报错现象.png

解决方法:

上传失败跨域问题设置.png
上传失败跨域问题设置2.png
上传失败跨域问题设置3.png

6. 给设置的RAM子账户添加OSS管理权限,不然也会上传失败

上传失败现象:

上传失败2问题(403)现象.png
解决方法:

上传失败2问题(403).png
上传失败2问题(403)_解决办法.png

7. 注意要到阿里云进行文件读取权限修改:

防止上传后,不能在本地读取到上传的文件
没有修改默认阿里云文件读取权限:

上传OSS后读取失败问题.png

修改方法:

上传OSS后读取失败问题解决1.png
上传OSS后读取失败问题解决2.png
上传OSS后读取失败问题解决3.png
上传OSS后读取失败问题解决4.png

完整代码示例:

<template>
  <div>
    <label for="upload" class="img-choose" :class="{upLoading: isUploading}">图片上传</label>
    <input type="file" name="" id="upload" accept="image/*" multiple style="display: none;" :disabled="isUploading" @change="onChange" ref="file">
    <p class="tips">一次可以选择多张图片,每次最多选择9张图片(单张图片大小 &lt; 1M)</p>
    <ul class="img-list">
      <li v-for="(item, index) in imgList" :key="index" :style="{background: `url(${item}) no-repeat center/cover`}"></li>
    </ul>
  </div>
</template>

<script>
// 引入阿里云oss包
import OSS from 'ali-oss'
const ACCESSKEY = {
  ID: '填写你自己的阿里云accessKeyId',
  SECRET: '填写你自己的阿里云accessKeySecret'
}
export default {
  data () {
    return {
      // 创建OSS对象
      client: new OSS({
        region: 'oss-cn-beijing',
        bucket: 'picuploadstudy',
        accessKeyId: ACCESSKEY.ID,
        accessKeySecret: ACCESSKEY.SECRET
      }),
      imgList: [],
      isUploading: false
    }
  },
  methods: {
    onChange () {
      // 可选链
      const picFiles = this.$refs?.file?.files
      console.log(picFiles)
      // 校验
      if (picFiles.length > 9) {
        alert('每次最多选择9张图片')
        return false
      }
      const files = []
      for (const file of picFiles) {
        const picSize = file.size / 1024 / 1024 // 单位转换成 M
        if (picSize > 1) {
          alert('单张图片大小不得超过 1M')
          return false
        }
        files.push(file)
      }
      // 图片上传至OSS
      // this.ossUploadPic(files)
      this.ossUploadPic2(files)
    },
    // 方法一:异步上传图片至阿里云OSS(Promise)
    ossUploadPic (files) {
      this.isUploading = true
      const upLoadRequest = []
      for (const file of files) {
        upLoadRequest.push(new Promise((resolve, reject) => {
          this.client.put(`${Math.random()}-${file.name}`, file).then(res => {
            resolve(res.url)
          }).catch(err => {
            console.log(err)
            reject(err)
          })
        }))
      }
      // 读取上传的图片
      Promise.allSettled(upLoadRequest).then(res => {
        console.log(res)
        const imgUrls = []
        for (const item of res) {
          if (item.status === 'fulfilled') {
            imgUrls.push(item.value)
          }
        }
        this.imgList = imgUrls
        this.isUploading = false
      }).catch(err => {
        console.log(err)
      })
    },
    // 方法二:异步同步化 async + await
    async ossUploadPic2 (files) {
      this.isUploading = true
      const imgUrls = []
      for (const file of files) {
        const res = await this.client.put(`${Math.random()}-${file.name}`, file)
        imgUrls.push(res.url)
      }
      this.imgList = imgUrls
      this.isUploading = false
    }
  }
}
</script>

<style scoped>
.img-choose {
  display: block;
  width: 100px;
  height: 50px;
  margin-left: 60px;
  line-height: 50px;
  color: #fff;
  background-color: #42B983;
  border-radius: 5px;
}
.tips {
  color: #999;
}
.upLoading {
  background-color: #ccc;
}
.img-list {
  margin-left: 60px;
}
.img-list > li{
  float: left;
  list-style: none;
  width: 150px;
  height: 100px;
  margin: 0 30px 30px 0;
  border: 1px solid #ccc;
}
</style>>

小提示: vue 的<style scoped>标签中添加scoped- - -改文件下面写的样式仅对本文件有效,对其他文件无效,就算不同文件之间有相同的类名,也不会相互影响,没有写scoped的话,可能有影响

评论区

零00
7粉丝

时光荏苒,我自清欢

0

0

0

举报