欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue實(shí)現(xiàn)拖拽或點(diǎn)擊上傳圖片

 更新時(shí)間:2021年09月09日 17:30:20   作者:你的小余童鞋  
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)拖拽或點(diǎn)擊上傳圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了vue實(shí)現(xiàn)拖拽或點(diǎn)擊上傳圖片的具體代碼,供大家參考,具體內(nèi)容如下

一、預(yù)覽圖

二、實(shí)現(xiàn)

點(diǎn)擊上傳思路:將input的type設(shè)置為“file”類型即可上傳文件。隱藏該input框,同時(shí)點(diǎn)擊按鈕時(shí),調(diào)取該input的點(diǎn)擊上傳功能。剩下的就是css優(yōu)化頁(yè)面了。

拖拽上傳思路:通過給拖拽框dropbox綁定拖拽事件,當(dāng)組件銷毀時(shí)解綁事件。在拖拽結(jié)束,通過event.dataTransfer.files獲取上傳的文件信息。然后在對(duì)文件進(jìn)行上傳服務(wù)器操作。

接下來請(qǐng)?jiān)试S我簡(jiǎn)單介紹一下各個(gè)組件:

upload.vue封裝了點(diǎn)擊上傳的邏輯,而進(jìn)度條則沒有做,后期可基于percent做參數(shù)繼續(xù)完善進(jìn)度條;uploadFormDialog.vue是父盒子,即點(diǎn)擊上傳按鈕后彈出的對(duì)話框,在該組件中需要完成頁(yè)面的布局,拖拽上傳等邏輯;

這樣封裝的意義是為了使得代碼更便于維護(hù)。

upload.vue 點(diǎn)擊上傳組件

<template>
    <!--upload.vue 點(diǎn)擊上傳組件 -->
    <div class="file-selector">
        <z-btn class="selector-btn" color="primary" @click="handleUpClick">
            選擇文件
        </z-btn>
        <input
            ref="input"
            class="file-selector-input"
            type="file"
            :multiple="multiple"
            :accept="accept"
            @change="handleFiles"
        />
    </div>
</template>
<script>
    import {debounce} from 'lodash/function';
    export default {
        data() {
            return {
                accept: '.jpg,.jpeg,.png,.gif',
                multiple: false,
                list: [], // 已選擇的文件對(duì)象
                uploadFinished: true, // 上傳狀態(tài)
                startIndex: 0, // 開始上傳的下標(biāo),用于追加文件
                maxSize: 10 * 1024 * 1024, //10M(size單位為byte)
                // source: this.$axios.CancelToken.source(), // axios 取消請(qǐng)求
            };
        },
        methods: {
            // 重置
            reset() {
                this.list = [];
                this.source.cancel();
                this.startIndex = 0;
                this.uploadFinished = true;
                this.$refs.input && (this.$refs.input.value = null);
            },
            // 調(diào)用上傳功能
            handleUpClick: debounce(function () {
                // 可在此維護(hù)一個(gè)上傳狀態(tài),上傳過程中禁用上傳按鈕
                // if (!this.uploadFinished) this.$message.info('即將覆蓋之前的文件~');
                this.$refs.input.click();
            }, 300),
            handleFiles(e) {
                const files = e?.target?.files;
                this.readFiles(files);
            },
            // 上傳之前將文件處理為對(duì)象
            readFiles(files) {
                if (!files || files.length <= 0) {
                    return;
                }
                for (const file of files) {
                    const url = window.URL.createObjectURL(file);
                    const obj = {
                        title: file.name.replace(/(.*\/)*([^.]+).*/ig, '$2'), // 去掉文件后綴
                        url,
                        file,
                        fileType: file.type,
                        status: 0, // 狀態(tài) -> 0 等待中,1 完成, 2 正在上傳,3 上傳失敗
                        percent: 0, // 上傳進(jìn)度
                    };
                    // 提前在 data 中定義 list,用來保存需要上傳的文件
                    this.list.unshift(obj);
                    this.$emit('fileList', this.list);
                }
                // 在 data 中定義 startIndex 初始值為 0,上傳完成后更新,用于追加上傳文件
                // this.startUpload(this.startIndex);
            },

        }
    };
</script>
<style lang="scss">
.file-selector {
    .selector-btn {
        &:hover {
            background-color: rgba($color: #2976e6, $alpha: 0.8);
            transition: background 180ms;
        }
    }

    &-input {
        display: none;
    }
}
</style>

uploadFormDialog.vue 上傳對(duì)話框

<template>
    <!-- 上傳dialog -->
    <form-dialog
        v-model="$attrs.value"
        :title="title"
        persistent
        :loading="loading"
        maxWidth="600px"
        min-height='400px'
        @cancel="handleCancle"
        @confirm="handleSubmit"
    >
        <div
            class="d-flex flex-row justify-space-between">
            <z-form style='width: 260px; height: 100%;'>
                <form-item label="圖片名稱"  required>
                    <z-text-field
                        v-model="formData.name"
                        outlined
                        :rules="rules"
                        :disabled='disabled'
                        placeholder="請(qǐng)輸入圖片名稱"
                    >
                    </z-text-field>
                </form-item>
                <form-item label="描述" required>
                    <z-textarea
                        v-model="formData.description"
                        outlined
                        :disabled='disabled'
                        placeholder="請(qǐng)輸入描述"
                        style="resize: none;"
                    >
                    </z-textarea>
                </form-item>
            </z-form>
            <div ref="pickerArea" class="rightBox">
                <div  class="uploadInputs d-flex flex-column justify-center align-center" :class="[ dragging ? 'dragging' : '']">
                    <div ref="uploadBg"  class="uploadBg my-2"></div>
                    <upload
                        ref="uploadBtn"
                        @fileList='fileList'
                    ></upload>
                    <div class="tip  mt-2">點(diǎn)擊上傳按鈕,或拖拽文件到框內(nèi)上傳</div>
                    <div class="tinyTip ">請(qǐng)選擇不大于 10M 的文件</div>
                </div>
            </div>
        </div>

    </form-dialog>

</template>
<script >
    import {debounce} from 'lodash/function';
    import upload from './upload';
    import {uploadImage} from '@/wv-main-admin/apis/image';

    export default {
        components: {
            upload
        },
        props: ['dialogData'],
        data() {
            return {
                dialogFlag: '',
                title: '新增/編輯圖片',
                loading: false,
                formData: {
                    name: '',
                    description: ''
                },
                disabled: false,
                rules: [v => !!v || '必填'],
                data: {},
                dragging: true, //是否拖拽
                bindDrop: false,
                fileInfo: {},
            };
        },

        mounted() {

        },
        beforeDestroy() {
            // 組件銷毀前解綁拖拽事件
            try {
                const dropbox = this.$refs.pickerArea;
                dropbox.removeEventListener('drop', this.handleDrop);
                dropbox.removeEventListener('dragleave', this.handleDragLeave);
                dropbox.removeEventListener('dragover', this.handleDragOver);
                this.bindDrop = false;
            } catch (e) { console.log(e, '======我是組件銷毀前解綁拖拽事件的異常'); }
        },
        methods: {
            //取消
            handleCancle() {
                // 關(guān)閉當(dāng)前彈框
                this.$emit('input', false);
                // 強(qiáng)制組件刷新
                this.$forceUpdate();
            },
            handleSubmit: debounce(function () {
                // 上傳單個(gè)文件
                const flag = this.checkMustsItem();
                if (flag) {
                    this.startUpload();
                    // 上傳完成,強(qiáng)制組件刷新
                    this.$forceUpdate();
                }
            }, 300),

            //監(jiān)聽子組件的值
            fileList(data) {
                this.fileInfo = data[0];
                this.formData.name = this.fileInfo.title;
                const uploadBg = this.$refs.uploadBg;
                //改變背景圖片
                uploadBg.style.backgroundImage = `url(${this.fileInfo.url})`;
            },
            bindEvents() {
                const dropbox = this.$refs.pickerArea;
                // 防止重復(fù)綁定事件,需要在 data 中初始化 bindDrop 為 false
                if (!dropbox || this.bindDrop) { return; }
                // 綁定拖拽事件,在組件銷毀時(shí)解綁
                dropbox.addEventListener('drop', this.handleDrop, false);
                dropbox.addEventListener('dragleave', this.handleDragLeave);
                dropbox.addEventListener('dragover', this.handleDragOver);
                this.bindDrop = true;
            },
            // 拖拽到上傳區(qū)域
            handleDragOver(e) {
                e.stopPropagation();
                e.preventDefault();
                this.dragging = true;
            },
            // 離開上傳區(qū)域
            handleDragLeave(e) {
                e.stopPropagation();
                e.preventDefault();
                this.dragging = false;
            },
            // 拖拽結(jié)束
            handleDrop(e) {
                e.stopPropagation();
                e.preventDefault();
                this.dragging = false;
                const files = e.dataTransfer.files;
                // 調(diào)用 <upload/> 組件的上傳功能
                this.$refs.uploadBtn && this.$refs.uploadBtn.readFiles(files);
            },
            // 上傳前需要校驗(yàn)文件
            checkFile(index) {
                const file = this.list[index];
                // 如果文件不存在,即全部文件上傳完成
                if (!file) {
                    // 上傳完成,向父組件拋出 success 事件
                    this.uploadFinished = true;
                    this.$emit('success', this.list);
                    // 清空上傳控件中的值,保證 change 事件能正常觸發(fā)
                    this.$refs.input.value = null; this.startIndex = index > 1 ? index - 1 : 0;
                    return false;
                }

                // 校驗(yàn)是否已上傳
                if (`${file.status}` === '1') {
                    this.startUpload(++index);
                    return false;
                }

                // 校驗(yàn)文件大小
                if (this.maxSize && file.file && file.file.size >= this.maxSize) {
                    this.startUpload(++index);
                    return false;
                }

                return true;
            },
            checkMustsItem() {
                if (!this.fileInfo.file) {
                    this.$message.warning('請(qǐng)上傳文件!');
                    return false;
                } if (!this.formData.name) {
                    this.$message.warning('請(qǐng)輸入文件名稱!');
                    return false;
                } if (!this.formData.description) {
                    this.$message.warning('請(qǐng)輸入文件描述!');
                    return false;
                }
                return true;
            },
            // 上傳單個(gè)文件
            startUpload() {
                this.loading = true;
                const params = {
                    type: 'image'
                };
                this.$set(params, 'file', this.fileInfo.file);
                this.$set(params, 'name', this.formData.name);
                this.$set(params, 'description', this.formData.description);
                uploadImage(params)
                    .then(res => {
                        this.loading = false;
                        if (res.code === 0) {
                            this.$message.success('上傳成功~');
                            this.$emit('refreshList', false);
                            this.$emit('input', false);
                        }
                    })
                    .catch(() => {
                        this.loading = false;
                    });
                // this.$axios({
                //     url: this.url, // 上傳接口,由 props 傳入
                //     method: 'post',
                //     data,
                //     withCredentials: true,
                //     cancelToken: this.source.token, // 用于取消接口請(qǐng)求
                //     // 進(jìn)度條
                //     onUploadProgress: e => {
                //         if (fileObj.status === 1) { return; } // 已上傳
                //         // 限定最大值為 99%
                //         const p = parseInt((e.loaded / e.total) * 99);
                //         if (e.total) {
                //             fileObj.status = 2; // 正在上傳
                //             fileObj.percent = p; // 更新上傳進(jìn)度
                //         } else {
                //             fileObj.status = 3; // 上傳失敗
                //         }
                //     },
                // })
                //     .then(response => {
                //         if (`${response.code}` === '200') {
                //             fileObj.status = 1;
                //             fileObj.percent = 100;
                //         } else {
                //             fileObj.status = 3;
                //         }
                //     })
                //     .catch(e => {
                //         console.log(e, '====error');
                //         fileObj.status = 3;
                //     })
                //     .finally(e => {
                //         console.log(e, '====error');

                //         this.startUpload(++index);
                //     });
                // 上傳完成
            },
        },
    };
</script>

<style lang='scss' scoped>
    .rightBox {
        width: 260px;
        height: 250px;
        border: 1px solid #ccc;
        margin-top: 18px;

        .uploadBg {
            width: 150px;
            height: 125px;
            background: url("../../../../assets/upload.png") no-repeat center center;
            background-size: contain;
        }
        .tip {
            font-size: 13px;
            color: rgba(0, 0, 0, 0.87);
        }
        .tinyTip {
            font-size: 12px;
            color: #8e8f9e;
        }
    }

</style>

注:以上代碼用到了我們自己封裝的組件庫(kù)和自己封裝的一些方法,請(qǐng)根據(jù)具體場(chǎng)景進(jìn)行相關(guān)的修改。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue 2.0學(xué)習(xí)筆記之Vue中的computed屬性

    Vue 2.0學(xué)習(xí)筆記之Vue中的computed屬性

    本篇文章主要介紹了Vue 2.0學(xué)習(xí)筆記之Vue中的computed屬性,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • 一篇文章帶你徹底搞懂VUE響應(yīng)式原理

    一篇文章帶你徹底搞懂VUE響應(yīng)式原理

    這篇文章主要介紹了一篇文章帶你徹底搞懂VUE響應(yīng)式原理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可任意參考一下,需要的朋友可以參考下
    2022-06-06
  • Element-ui 自帶的兩種遠(yuǎn)程搜索(模糊查詢)用法講解

    Element-ui 自帶的兩種遠(yuǎn)程搜索(模糊查詢)用法講解

    這篇文章主要介紹了Element-ui 自帶的兩種遠(yuǎn)程搜索(模糊查詢)用法講解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 詳解Vue源碼學(xué)習(xí)之雙向綁定

    詳解Vue源碼學(xué)習(xí)之雙向綁定

    這篇文章主要介紹了Vue源碼學(xué)習(xí)之雙向綁定,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vue中響應(yīng)式布局如何將字體大小改成自適應(yīng)

    vue中響應(yīng)式布局如何將字體大小改成自適應(yīng)

    這篇文章主要介紹了vue中響應(yīng)式布局如何將字體大小改成自適應(yīng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Vue2 Element el-table多選表格控制選取的思路解讀

    Vue2 Element el-table多選表格控制選取的思路解讀

    這篇文章主要介紹了Vue2 Element el-table多選表格控制選取的思路解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 詳解Vue中$props、$attrs和$listeners的使用方法

    詳解Vue中$props、$attrs和$listeners的使用方法

    本文主要介紹了Vue中$props、$attrs和$listeners的使用詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • vue中el-tree增加節(jié)點(diǎn)后如何重新刷新

    vue中el-tree增加節(jié)點(diǎn)后如何重新刷新

    這篇文章主要介紹了vue中el-tree增加節(jié)點(diǎn)后如何重新刷新,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue element動(dòng)態(tài)渲染、移除表單并添加驗(yàn)證的實(shí)現(xiàn)

    vue element動(dòng)態(tài)渲染、移除表單并添加驗(yàn)證的實(shí)現(xiàn)

    這篇文章主要介紹了vue element動(dòng)態(tài)渲染、移除表單并添加驗(yàn)證的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • vue+element實(shí)現(xiàn)錨點(diǎn)鏈接方式

    vue+element實(shí)現(xiàn)錨點(diǎn)鏈接方式

    這篇文章主要介紹了vue+element實(shí)現(xiàn)錨點(diǎn)鏈接方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評(píng)論