1. IntroductionThe effect is as follows 2. Ideas Two ways to upload files1. From form <form method="post" enctype="multipart/from-data" action="api/upload" > <input type="file name="file"> <button type="submit">Submit</button> </form> The method attribute of form specifies a "post" request, which sends data to the server through an HTML form and returns the modified result of the server. In this case, the Content-Type is set by setting the correct enctype attribute in the <form> element. The enctype attribute of form specifies how the form data should be encoded before being sent to the server.
2. JavaScript asynchronous request form We know that the FormData interface provides a way to construct key/value pairs that represent form data, and can easily send data through the XMLHttpRequest.send() method. This interface and this method are quite simple and direct. If the outbound encoding is set to "multipart/form-data", it will use the same format as the form. var formdata = new FormData(); // Create a FormData object formdata.append("name","laotie"); // Add new attribute values through the append() method... // For more methods, please click the link below FormData Interface 3. Life CycleThe upload component also has its life cycle beforeUpload --> uploading --> fileUploaded or uploadedError 4. Code DraftIn this example, the upload component is developed using js asynchronous request <input type="file" name="file" @change.prevent="handleFileChange"> // Create an input of type file to trigger file upload. You can hide the input later and customize the style. // When customizing the style, you can use slot to distinguish the styles of different upload states (loading, success, default) const handleFileChange = (e:Event)=>{ const target = e.target as HTMLInputElement const files = Array.from(target.files)// Note that what is obtained here is a class array if(files){ // Get the file const uploadedFile = files[0] if(!validateFormat) return // ...This is just a way of thinking, and the specific verification will not be described here // Do some verification before uploading the file, such as file format, size, etc. // If it does not meet the requirements, no more requests will be sent const formData = new FormData() formData.append(uploadedFile.name,uploadedFile) axios.post('/upload',formData,{ headers:{ // Note to set the encoding type 'Content-Type': 'multipart/form-data' } }).then(res=>{ console.log('Upload successful') }).catch(error =>{ // File upload failed}).finally(()=>{ // File upload completed, whether successful or failed // Here you can clear input.value }) } } 5. Specific implementation// Upload.vue <template> <div class="upload-container"> <div class="upload-box" @click.prevent="triggerUpload" v-bind="$attrs"> <slot name="loading" v-if="fileStatus==='loading'"> <button class="btn btn-primary">Uploading</button> </slot> <slot name="uploaded" v-else-if="fileStatus==='success'" :uploadedData="fileData"> <button class="btn btn-primary">Upload successful</button> </slot> <slot v-else name="default"> <button class="btn btn-primary">Click to upload</button> </slot> </div> <input type="file" class="file-input d-none" name="file" ref="uploadInput" @change="hanldeInput"/> </div> </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: { // Upload url action: { type: String, required: true }, // Verification before uploading, a function that returns a Boolean value beforeUpload: { type: Function as PropType<FunctionProps> }, // Uploaded data, used to determine status or initialize display 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('File uploaded successfully', res) fileStatus.value = 'success' fileData.value = res.data ctx.emit('file-uploaded-success', res.data) }).catch(error => { console.log('File upload failed', error) fileStatus.value = 'error' ctx.emit('file-uploaded-error', error) }).finally(() => { console.log('File upload completed') if (uploadInput.value) { uploadInput.value.value = '' } }) } } return { uploadInput, triggerUpload, hanldeInput, fileStatus, fileData } } }) </script> Example of use: <template> <div 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"> <div class="uploaded-area"> <img :src="slotProps.uploadedData.data.url"/> <h3>Click to re-upload</h3> </div> </template> <template #default> <h2>Click to upload header image</h2> </template> <template #loading> <div class="d-flex"> <div class="spinner-border text-secondary" role="status"> <span class="sr-only"></span> </div> </div> </template> </upload> </div> </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() //Create a responsive data let imageId = '' onMounted(() => { .... // The logic is omitted here, get the initialization data image if (image) { uploadedData.value = { data: image } } }) // Verify before uploading, return Boolean value const beforeUpload = (file:File) => { const res = beforeUploadCheck(file, { format: ['image/jpeg', 'image/png'], size: 1 }) const { error, passed } = res if (error === 'format') { createMessage('Uploaded images can only be in JPG/PNG format!', 'error') } if (error === 'size') { createMessage('Uploaded image size cannot exceed 1MB', 'error') } return passed } // After the upload is successful, you can get the imageId for subsequent processing, such as creating a form. const hanldeUploadSuccess = (res:ResponseProps<ImageProps>) => { createMessage(`Upload image ID ${res.data._id}`, 'success') if (res.data._id) { imageId = res.data._id } } return { beforeUpload, hanldeUploadSuccess, uploadedData } } }) </script> <style> .create-post-page{ padding:0 20px 20px; } .create-post-page .upload-box{ height:200px; cursor: pointer; overflow: hidden; } .create-post-page .upload-box img{ width: 100%; height: 100%; object-fit: cover; } .uploaded-area{ position: relative; } .uploaded-area:hover h3{ display: block; } .uploaded-area h3{ display: none; position: absolute; color: #999; text-align: center; width: 100%; top:50% } </style> The above is the details of Vue's upload component implementation. For more information about the Vue upload component, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: MySQL 8.0.13 installation and configuration method graphic tutorial under Windows 64 bit
>>: CentOS 7.6 installation of MySQL 5.7 GA version tutorial diagram
Table of contents Introduction The following is a...
Although I have run some projects in Docker envir...
1. Elements and tags in HTML <br />An eleme...
Table of contents 1. What is Promise 2. Basic usa...
At work, we often need remote servers and often e...
Table of contents 1: Prepare https certificate 2:...
Preface This article contains 1. Several major co...
The installation of mysql5.7.18zip version on Win...
1. Connect to MySQL Format: mysql -h host address...
<br />Since the Ministry of Foreign Affairs ...
Docker installation Use the official installation...
This article shares the specific code of the WeCh...
<br />The following are the problems I encou...
Preface: In the MySQL system, there are many diff...
Table of contents 1. Download 2. Installation 3. ...