vue集成文件上传插件(vue 实现上传组件)
类别:编程学习 浏览量:802
时间:2022-01-21 00:07:29 vue集成文件上传插件
vue 实现上传组件目录
- 1.介绍
- 2.思路
- 文件上传的两种实现方式
- 3.生命周期
- 4.代码草稿
- 5.具体实现
效果如下图
2.思路
文件上传的两种实现方式
1.From形式
<form method="post" enctype="multipart/from-data" action="api/upload" > <input type="file name="file"> <button type="submit">Submit</button> </form>
form的method属性指定为 "post" 请求,通过HTML表单发送数据给服务器,并返回服务器的修改结果,在这种情况下Content-Type是通过在<form>元素中设置正确的enctype属性。
form的enctype属性规定在发送到服务器之前应该如何对表单数据进行编码。
- application/x-www-form-urlencoded(默认值):表示在发送前编码所有字符,数据被编码成以"&"分隔的键值对,同时以"="分隔键和值,("name=seven&age=19")。不支持二进制数据。
- multipart/form-data:支持二进制数据(上传文件时必须指定)
2.JavaScript异步请求形式
我们知道 FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send()方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 "multipart/form-data",它会使用和表单一样的格式。
var formdata = new FormData(); // 创建FormData对象 formdata.append("name","laotie"); // 通过append()方法添加新的属性值 ... // 更多方法请点下面链接
FormData接口
3.生命周期上传组件也有它的生命周期
beforeUpload --> uploading --> fileUploaded 或者 uploadedError
4.代码草稿本例中采用js异步请求的方式开发上传组件
<input type="file" name="file" @change.prevent="handleFileChange"> // 创建一个file类型的input,用于触发文件上传,后面可以把input隐藏掉,自定义好看的样式 // 自定义样式的时候可以用slot区分不同上传状态的样式(loading,success,defult)
const handleFileChange = (e:Event)=>{ const target = e.target as HTMLInputElement const files = Array.from(target.files)// 注意这里取得的是一个类数组 if(files){ // 取得文件 const uploadedFile = files[0] if(!validateFormat) return // ...这里只是提供一种思路,具体校验不再讲述 // 在这里做一些上传文件前的校验,比如文件格式,大小等, // 不符合要求的话就不在继续发送请求 const formData = new FormData() formData.append(uploadedFile.name,uploadedFile) axios.post('/upload',formData,{ headers:{ // 注意设置编码类型 'Content-Type': 'multipart/form-data' } }).then(res=>{ console.log('上传成功') }).catch(error =>{ // 文件上传失败 }).finally(()=>{ // 文件上传完成,无论成功还是失败 // 这里可以清除一下input.value }) } }
// Upload.vue <template> <li class="upload-container"> <li class="upload-box" @click.prevent="triggerUpload" v-bind="$attrs"> <slot name="loading" v-if="fileStatus==='loading'"> <button class="btn btn-primary">上传中</button> </slot> <slot name="uploaded" v-else-if="fileStatus==='success'" :uploadedData="fileData"> <button class="btn btn-primary">上传成功</button> </slot> <slot v-else name="default"> <button class="btn btn-primary">点击上传</button> </slot> </li> <input type="file" class="file-input d-none" name="file" ref="uploadInput" @change="hanldeInput"/> </li> </template> <script lang="ts"> import { defineComponent, ref, PropType, watch } from 'vue' import axios from 'axios' type UploadStatus = 'ready' | 'loading' | 'success' | 'error' type FunctionProps = (file:File) => boolean export default defineComponent({ name: 'Upload', inheritAttrs: false, props: { // 上传的url action: { type: String, required: true }, // 上传之前的校验,是一个返回布尔值的函数 beforeUpload: { type: Function as PropType<FunctionProps> }, // 上传好的数据,用来判断状态或做初始化展示 uploadedData: { type: Object } }, emits: ['file-uploaded-success', 'file-uploaded-error'], setup(props, ctx) { const uploadInput = ref<null | HTMLInputElement>(null) const fileStatus = ref<UploadStatus>(props.uploadedData ? 'success' : 'ready') const fileData = ref(props.uploadedData) watch(() => props.uploadedData, (val) => { if (val) { fileStatus.value = 'success' fileData.value = val } }) const triggerUpload = () => { if (uploadInput.value) { uploadInput.value.click() } } const hanldeInput = (e:Event) => { const target = e.target as HTMLInputElement const files = target.files console.log(target) if (files) { const uploadFile = Array.from(files) const validateFormat = props.beforeUpload ? props.beforeUpload(uploadFile[0]) : true if (!validateFormat) return fileStatus.value = 'loading' const formData = new FormData() formData.append('file', uploadFile[0]) axios.post(props.action, formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then(res => { console.log('文件上传成功', res) fileStatus.value = 'success' fileData.value = res.data ctx.emit('file-uploaded-success', res.data) }).catch(error => { console.log('文件上传失败', error) fileStatus.value = 'error' ctx.emit('file-uploaded-error', error) }).finally(() => { console.log('文件上传完成') if (uploadInput.value) { uploadInput.value.value = '' } }) } } return { uploadInput, triggerUpload, hanldeInput, fileStatus, fileData } } }) </script>
使用示例:
<template> <li class="create-post-page"> <upload action="/upload" :beforeUpload="beforeUpload" :uploadedData="uploadedData" @file-uploaded-success="hanldeUploadSuccess" class="d-flex align-items-center justify-content-center bg-light text-secondary w-100 my-4" > <template #uploaded="slotProps"> <li class="uploaded-area"> <img :src="slotProps.uploadedData.data.url"/> <h3>点击重新上传</h3> </li> </template> <template #default> <h2>点击上传头图</h2> </template> <template #loading> <li class="d-flex"> <li class="spinner-border text-secondary" role="status"> <span class="sr-only"></span> </li> </li> </template> </upload> </li> </template> <script lang="ts"> import { defineComponent, ref, onMounted } from 'vue' import Upload from '../components/Upload.vue' import createMessage from '../components/createMessage' export default defineComponent({ name: 'CreatePost', components: { Upload }, setup() { const uploadedData = ref() //创建一个响应式数据 let imageId = '' onMounted(() => { .... // 这里有逻辑省略了,取到初始化数据image if (image) { uploadedData.value = { data: image } } }) // 上传前校验,返回布尔值 const beforeUpload = (file:File) => { const res = beforeUploadCheck(file, { format: ['image.jpg" alt="vue集成文件上传插件(vue 实现上传组件)" border="0" />
以上就是vue 实现上传组件的详细内容,更多关于vue 上传组件的资料请关注开心学习网其它相关文章!
您可能感兴趣
- vue3 动态生成组件(如何在vue3.0+中使用tinymce及实现多图上传文件上传公式编辑功能)
- vue怎么配置到idea(idea编译器vue缩进报错问题场景分析)
- vue购物车简单项目(vue实现简单购物车案例)
- vuex中action的值怎么接(vuex中Getter的用法详解)
- vue.js 怎么做插件(Vue.js实现音乐播放器)
- vue动态路由实现权限控制(vue2/vue3路由权限管理的方法实例)
- vue组件开发步骤(解析如何自动化生成vue组件文档)
- vue左侧边栏的制作(Vue+Vant实现顶部搜索栏)
- vue函数中的默认参数(Vue3中SetUp函数的参数props、context详解)
- vue 为什么使用虚拟dom(Vue虚拟Dom到真实Dom的转换)
- vue常用的指令和修饰符(Vue中 Vue.prototype使用详解)
- springbootvue项目代码(Vue+SpringBoot实现支付宝沙箱支付的示例代码)
- vue手动清除keepalive缓存(vue中keep-alive组件的用法示例)
- vue设置div大小(Vue实现div滚轮放大缩小)
- vuetable表格合并(vue-table实现添加和删除)
- vue滑动切换页面(vue实现点击翻转效果)
- TVB新剧《黯夜守护者》将播,陈展鹏陈炜首次合作探讨人性(TVB新剧黯夜守护者将播)
- 新晋小花被称女版吴卓羲 将取代滕丽名成为TVB新一代御用女警(新晋小花被称女版吴卓羲)
- 艺人吴卓羲10年警察生涯,演足10年阿Sir,系咩玩法(艺人吴卓羲10年警察生涯)
- 菲律宾潜水(菲律宾潜水价格)
- 泰国人妖(变性手术生殖器要割掉吗)
- 泰国美女(泰国人妖和女性如何区分)
热门推荐
- ASP.NET生成二维码
- mysql 性能调优技巧(4 款 MySQL 调优工具,公司大神都在用!)
- mysql的null值跟空值(你知道mysql中空值和null值的区别吗)
- css中的margin属性(css布局之负margin妙用及其他实现)
- python数据分析用到的模块(python模块之subprocess模块级方法的使用)
- html中table怎么用(详解CSS的table-layout属性的用法)
- sql数据分页如何查询(SQL分页查询方式汇总)
- ui界面的测试用例(AmazeUI中模态框的实现)
- mysql 如何选择隔离级别(全面解析MySQL中的隔离级别)
- 微信小程序即时聊天功能怎么实现(微信小程序实现聊天室功能)