vue oss上传文件

介绍了一个基于Vue的文件上传组件,该组件利用阿里云OSS进行文件的存储,支持拖拽上传、限制上传文件类型及大小,并通过axios请求获取上传所需的token。

创建组件:testUpload.vue

<template>
    <div>
        <el-upload
            class="upload-demo"
            ref="upload"
            drag
            list-type="picture"
            :before-upload="beforeUpload"
            :http-request="handleHttpRequest"
            :limit="files"
            :disabled="disabled"
            multiple
            action=""
            :on-remove="onRemoveChange"
            :file-list="fileList">
            <el-button size="small" type="primary">点击上传</el-button>
            <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
        </el-upload>
    </div>
</template>
 
<script type="text/ecmascript-6">
    import OSS from 'ali-oss'
    import request from '@/router/axios';
    import { imgUrl } from '@/config/env' 	//预览图片的前缀
    //将渲染的内容导出
    export default{
        data(){
            return {
                region: 'oss-cn-shenzhen', 
                bucket: '',	//这里选择OSS容器
                url: '',//后台获取token地址
                ClientObj: null,
                dataObj: {},
                files: 10,
                disabled: false,
            }
        },
        props:['fileList'],
        methods: {
            getDate(){ 
                const date = new Date(),
                    year = date.getFullYear(),
                    month = date.getMonth() > 9 ? date.getMonth() + 1 : `0${date.getMonth() + 1}`,
                    day = date.getDate() > 9 ? date.getDate() : `0${date.getDate()}`,
                    hh = date.getHours() > 9 ? date.getHours() : `0${date.getHours()}`,
                    mm = date.getMinutes() > 9 ? date.getMinutes() : `0${date.getMinutes()}`;
                    return `${year}${month}${day}${hh}${mm}`;
            },
            getAliToken(){ //获取Token
                return new Promise((resolve, reject) => {
                    request({
                        method: 'GET',
                        url: this.url
                    }).then(res => {
                        console.log(res)
                        if (res.data.code == 200) {
                            const {bucketName, accessKeyId, accessKeySecret, securityToken} = res.data.data;
                            this.dataObj = {
                                'region': this.region,
                                'bucket': bucketName,
                                'accessKeyId': accessKeyId,
                                'accessKeySecret': accessKeySecret,
                                'stsToken':securityToken,
                                'secure':true
                            };
                            resolve(true);
                        } else {
                            reject(false);
                        }
                    }).catch(err => {
                        console.log(err);
                        reject(false);
                    })
                })
            },
            beforeUpload(file){
                return new Promise((resolve, reject) => {
                    this.getAliToken().then(response => {
                        if (response) {
                            resolve(response);
                        } else {
                            reject(response);
                        }
                    }).catch(err => {
                        console.log(err);
                        reject(err);
                    });
                })
            },
            async handleHttpRequest(option){ //上传OSS
                console.log(this.dataObj)
                try {
                    let vm = this;
                    vm.disabled = true;
                    const file = option.file;
                    //随机命名
                    const random_name = 'vsdwq/'+this.random_string(6) + '_' + new Date().getTime() + '.' + file.name.split('.').pop();
                    new OSS(this.dataObj).multipartUpload(random_name, file).then(res=>{
                        console.log(res)
                        let obj = {
                            fileList : [{ 'name': res.name, 'url': imgUrl + res.name }],
                            img:res.name
                        }
                        this.$emit('successImg',obj)
                        this.$message({
                            showClose: true,
                            message: '上传成功',
                            type: 'success'
                        });
                        vm.disabled = false;
                    }).catch(err=>{
                        console.log(err)
                        this.disabled = false;
                        this.$message({
                            showClose: true,
                            message: '上传失败',
                            type: 'error'
                        });
                    })
                } catch (error) {
                    console.error(error);
                    this.disabled = false;
                    this.$message({
                        showClose: true,
                        message: '上传失败',
                        type: 'error'
                    });
                }
            },
            // 随机生成文件名
            random_string(len) {
                len = len || 32;
                let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz12345678', maxPos = chars.length, pwd = '';
                for (let i = 0; i < len; i++) {
                    pwd += chars.charAt(Math.floor(Math.random() * maxPos));
                }
                return pwd;
            },
            onRemoveChange(file, fileList){ //点击上传图片列表×  清空
                this.$emit('onremove',{fileList:[],bannerImg:''})
            }
        },
    }
</script>
 
<style>
    /**渲染内容的样式**/
 .el-upload-dragger{
    background-color: #fff;
    border-radius: 6px;
    box-sizing: border-box;
    text-align: center;
    position: relative;
    overflow: hidden;
    border:none;
    width: auto;
    height: auto;
 }
 .el-upload__tip{
     margin-top: 0;
 }
</style>

使用

<template>
    <div>
        <testUpload :fileList="fileList" @onremove="onremove" @successImg="successImg" />
    </div>
</template>

<script>
import request from '@/router/axios';
import testUpload from '../components/testUpload';
import { imgUrl } from '@/config/env'

export default {
    name:'',
    data(){
        return {
            fileList: [],
        }
    },
    components:{testUpload },
    methods: {
        successImg(res){
            console.log(res)
            this.fileList = res.fileList
        },
        onremove(res){
            console.log(res)
            this.fileList = res.fileList
        }
    }
}
</script>

<style scope>
    #banner{
        padding: 20px 40px;
        background: #fff;
    }
    .el-upload-list{
        width: 60%;
    }
    .el-table th>.cell{
        color: #000;
    }
    .el-table--border th{
        background: #fafafa;
    }
    .upload-box{
        position: relative;
        display: inline-block;
        cursor: pointer;
    }
    .fileclass{
        opacity: 0;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        width: 100%;
        height: 100%;
        cursor: pointer;
    }
    .BANNER{
        height: 80%;
        overflow: auto;
    }
    .BANNER::-webkit-scrollbar{
        width: 5px;                     /*高宽分别对应横竖滚动条的尺寸*/
        height: 1px;
    }
    .BANNER::-webkit-scrollbar-thumb {/*滚动条里面小方块*/
        border-radius: 10px;
        background: rgba(144,147,153,.5);
    }
    .BANNER::-webkit-scrollbar-track {/*滚动条里面轨道*/
        border-radius: 10px;
        background: #fff;
    }
</style>
### 集成阿里云 OSS 实现文件上传 #### 准备工作 为了在 Vue 项目中集成阿里云 OSS 文件上传功能,需先完成一些准备工作。这包括获取必要的配置参数以及安装依赖库。 - 获取 `AccessKeyId` 和 `AccessKeySecret`,并创建 Bucket[^1]。 - 安装 `ali-oss` 库来简化与 OSS 的交互操作: ```bash npm install ali-oss --save ``` #### 初始化 SDK 并设置签名服务 由于安全原因,在前端直接使用 Access Key 是不推荐的做法;因此通常会通过后端提供临时授权 Token 或者 STS (Security Token Service) 来访问资源。这里假设已经有一个可以返回签名 URL 的 API 接口 `/api/getSTS` 可供调用[^2]。 初始化 SDK 后可以通过如下方式连接至指定存储空间: ```javascript import OSS from 'ali-oss'; const client = new OSS({ region: '<YourRegion>', // 如 oss-cn-hangzhou accessKeyId: '<YourAccessKeyId>', accessKeySecret: '<YourAccessKeySecret>', stsToken: '<YourSTSToken>', // 如果使用了 STS 则需要此字段 bucket: '<YourBucketName>' }); ``` #### 构建上传组件 接下来构建一个简单的表单用于选择要上传文件,并处理提交事件触发实际的数据传输过程。下面是一个基本的例子展示如何利用上述客户端实例执行上传动作: ```html <template> <div class="upload-container"> <input type="file" @change="handleChange"/> <button @click="handleUpload">点击上传</button> </div> </template> <script setup lang="ts"> import { ref } from "vue"; import OSS from "ali-oss"; let fileInputValue = ref<File | null>(null); async function handleChange(event:Event){ const target = event.target as HTMLInputElement; if(target.files && target.files.length>0){ fileInputValue.value=target.files.item(0)!; } } async function handleUpload(){ try{ await client.put(`/${fileInputValue.value!.name}`, fileInputValue.value!); console.log('File uploaded successfully'); }catch(error){ console.error('Failed to upload:', error.message); } } </script> ``` 以上代码片段展示了怎样监听输入框变化并将选中的文件保存起来以便后续发送给服务器。当按钮被按下时,则尝试将选定文件上传到预先定义好的路径下。 #### 大文件分片上传支持 对于较大的文件来说,建议采用分片的方式来进行更高效的管理。这种方式不仅可以提高成功率还能更好地应对网络波动等问题。具体做法是在每次请求前计算出当前块的信息(比如序号、大小),然后按照顺序依次传递直到全部完成为止。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值