摘要

当使用 Vue.js 的 CDN 来实现一个简单的上传图片组件时,你可以利用 Vue 的数据绑定和事件处理能力,结合 HTML 和 CSS,轻松地创建一个交互式的图片上传界面。以下是一个示例:

代码结构

image.png

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vue上传图片</title>
        <script src="vue.min.js"></script>
        <script src="axios.min.js"></script>
        <style>
            body {
                font-family: Arial, sans-serif;
                margin: 0;
                padding: 0;
                background: #f1f1f1;
            }
            
            .container {
                width: 100%;
                margin: 50px auto 0;
            }
            
            .container .upload-pannel {
                width: 500px;
                background: #fff;
                border-radius: 10px;
                margin: 20px auto 0;
                overflow: hidden;
            }
            .container .upload-pannel .pannel-title {
                width: 90%;
                margin: 20px auto;
                font-size: 15px;
                color: #333;
                font-weight: bold;
                display: block;
            }
            .container .upload-pannel .file-select{
                width: 90%;
                height: 250px;
                border: 2px dashed rgb(59,94,225);
                background: rgba(59,94,225,0.05);
                margin: 20px auto;
                display: block;
                border-radius: 10px;
                position: relative;
            }
            .container .upload-pannel input[type="file"]{
                width: 100%;
                height: 100%;
                opacity: 0;
                position: absolute;
                left: 0;
                top: 0;
            }
            .container .upload-pannel .upload-icon{
                width: 40px;
                height: 35px;
                display: block;
                margin: 0 auto;
                line-height: 250px;
            }
            .container .upload-pannel .upload-icon img{
                width: 40px;
                height: 35px;
            }
            .container .upload-pannel .file-select .upload-text{
                text-align: center;
                display: block;
                font-size: 14px;
                color: #999;
                line-height: 230px;
            }
            .container .upload-pannel .upload-progress{
                width: 90%;
                height: 60px;
                background: #f1f1f1;
                margin: 20px auto;
                border-radius: 10px;
                overflow: hidden;
            }
            .container .upload-pannel .upload-progress .progress-bar-container {
                position: relative;
                width: 90%;
                height: 10px;
                margin: 25px auto;
                background: #f1f1f1;
                border-radius: 10px;
                overflow: hidden;
            }
            
            .container .upload-pannel .upload-progress .progress-bar {
                height: 100%;
                background: rgb(59,94,225);
                border-radius: 10px;
                transition: width 0.3s ease-in-out;
            }
            
            .container .upload-pannel .upload-progress .progress-text {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                font-size: 12px;
                color: #fff;
            }
            
            .container .upload-pannel .imgPreview{
                width: 90%;
                margin: 20px auto;
                display: block;
            }
        
        </style>
    </head>
    <body>
        <div id="app"></div>
        <script>
            new Vue({
                el: '#app',
                data() {
                return {
                    imgUrl: '',
                    uploadProgress: 0,
                    uploadProgressbg: false
                };
              },
              methods: {
                async handleImageUpload(event) {
                    const file = event.target.files[0];
                    if (file) {
                        
                        // 上传图片
                        this.uploadProgressbg = true;
                        const formData = new FormData();
                        formData.append('image', file);
                        
                        try {
                            const response = await axios.post('upload.php', formData, {
                            onUploadProgress: progressEvent => {
                                
                                // 改变进度条
                                this.uploadProgress = Math.round((progressEvent.loaded / progressEvent.total) * 100);
                            },
                        });
                        
                        const imageUrl = response.data.url;
                        if (imageUrl) {
                            
                            // 上传成功
                            this.imgUrl = imageUrl;
                        }
                        
                        } catch (error) {
                            
                            // 上传失败
                            console.error('Error uploading image:', error);
                        } finally {
                        
                        // 隐藏进度条
                        setTimeout(() => {
                            this.uploadProgress = 0;
                            this.uploadProgressbg = false;
                        }, 1500);
                    }
                  }
                },
            },
            template: `
                <div class="container">
                        <div class="upload-pannel">
                            <span class="pannel-title">Vue.js 图片上传</span>
                            <span class="file-select">
                                <input type="file" @change="handleImageUpload">
                                <span class="upload-icon">
                                    <img src="upload.png" />
                                </span>
                                <span class="upload-text">仅支持上传jpg、png、gif格式的图片</span>
                            </span>
                            <div class="upload-progress" v-if="uploadProgressbg == true">
                                <div class="progress-bar-container" :class="{ active: uploadProgressbg }">
                                    <div class="progress-bar" :style="{ width: uploadProgress + '%' }"></div>
                                <span class="progress-text" v-if="uploadProgressbg">{{ uploadProgress }}%</span>
                            </div>
                        </div>
                        <img v-if="imgUrl" :src="imgUrl" class="imgPreview">
                    </div>
                </div>`,
            });
        </script>
    </body>
</html>

动图演示

作者

TANKING

源码下载

https://afdian.net/item/ffa3292a337c11ee9a8c5254001e7c00


TANKING
4.8k 声望511 粉丝

热爱分享,热爱创作,热爱研究。