在Vue中使用Filepond上傳文件以及樣式坑

Filepond是我個(gè)人最喜歡的上傳組件之一,在功能全面的基礎(chǔ)上提供了額及其強(qiáng)大的可定制性以及最美觀的樣式。雖然官網(wǎng)有vue下的使用指南,但是并不是很全面。

在開發(fā)我的開源圖床框架PARA時(shí),我選擇了Filepond作為我的前端上傳插件。它具備官方的前端框架支持和幾乎所有你能想到的定制屬性。更棒的是,它在nuxt下依然非常好用。

基本使用

安裝:

npm install vue-filepond filepond --save

如果你和我一樣更喜歡yarn,那么命令為:

yarn add vue-filepond filepond

然后應(yīng)該就可以在vue中使用<file-pond>組件了,當(dāng)然這通常不夠。

掛載插件:

Filepond提供了很多插件,我通常會(huì)選擇可以預(yù)覽上傳圖片的ImagePreview和文件大小以及類型插件FileValidateTypeFileValidateSize。插件要使用組件局部聲明的方式,掛載在filepond組件上。同時(shí)如果插件需要額外的css文件也需要提前引入,對(duì)于我的插件配置來說,代碼應(yīng)該像這樣:

//index.vue
import vueFilePond from "vue-filepond";
import "filepond/dist/filepond.min.css";
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginFileValidateType from "filepond-plugin-file-validate-type";
import FilepondPluginFileValidateSize from "filepond-plugin-file-validate-size";

const FilePond = vueFilePond(
  FilePondPluginFileValidateType,
  FilepondPluginFileValidateSize,
  FilePondPluginImagePreview
);

配置參數(shù)

官網(wǎng)的示例如下:

<template>
  <div id="app">
    
    <file-pond
        name="test"
        ref="pond"
        class-name="my-pond"
        label-idle="Drop files here..."
        allow-multiple="true"
        accepted-file-types="image/jpeg, image/png"
        v-bind:files="myFiles"
        v-on:init="handleFilePondInit"/>
    
  </div>
</template>

<script>
// Import FilePond
import vueFilePond from 'vue-filepond';

// Import plugins
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.esm.js';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.esm.js';

// Import styles
import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';

// Create FilePond component
const FilePond = vueFilePond( FilePondPluginFileValidateType, FilePondPluginImagePreview );

export default {
    name: 'app',
    data: function() {
        return { myFiles: ['index.html'] };
    },
    methods: {
        handleFilePondInit: function() {
            console.log('FilePond has initialized');

            // example of instance method call on pond reference
            this.$refs.pond.getFiles();
        }
    },
    components: {
        FilePond
    }
};
</script>

如果只看官網(wǎng)的文檔,可定制的項(xiàng)似乎很少,但是根據(jù)在devtool中查看的結(jié)果,幾乎所有的定制項(xiàng)組件都有,所以直接在組件上設(shè)置就可以了。

坑:

其實(shí)我寫這篇文章主要是為了記錄這個(gè)樣式上的坑:

背景:

在框架中我設(shè)置的用戶權(quán)限組配置項(xiàng)有“是否可以多文件上傳這一項(xiàng)”,所以組件多文件上傳的開關(guān)是動(dòng)態(tài)綁定的。于此同時(shí)網(wǎng)站的首頁為了美觀設(shè)置了{(lán)height:100vh;overflow:hidden}來保證始終占據(jù)整屏且沒有滾動(dòng)欄。這就導(dǎo)致了如果用戶一次上傳了過多的文件,上傳列表將會(huì)超出屏幕。

官方解決方案:

為組件的根元素設(shè)置最大高度,當(dāng)設(shè)置了最大高度時(shí),如果超過了最大高度將會(huì)自動(dòng)顯示滾動(dòng)條:

.filepond--root {
    max-height: 10em;
}

但是這也帶來了一個(gè)問題,因?yàn)楣俜皆谏山M件的時(shí)候,單文件上傳和多文件上傳的DOM結(jié)構(gòu)是不一樣的(可能官方以為只允許單文件上傳的時(shí)候開發(fā)者是想不到設(shè)置高度這碼事的)

問題:

單文件的組件邏輯為:將圖片拖入時(shí),有提示信息和“支撐元素高度”的label元素就會(huì)隱藏

普通的上傳框

我來抽象一下它的DOM樹:

<div class="filepond--wrapper">
    <div class="filepond--root filepond--hopper"  style="height: 76px;">
        <input class="filepond--browser" type="file" accept="image/jpeg,image/png">
        <div class="filepond--drop-label" style="transform: translate3d(0px, 0px, 0px); opacity: 1;">
            <label aria-hidden="true">將文件拖入框中,或點(diǎn)擊<span class="filepond--label-action" tabindex="0">選擇</span></label></div>
        <div class="filepond--list-scroller" style="transform: translate3d(0px, 0px, 0px);">
            <ul class="filepond--list" role="list"></ul>
        </div>
        <div class="filepond--panel filepond--panel-root">
            <div class="filepond--panel-top filepond--panel-root"></div>
            <div class="filepond--panel-center filepond--panel-root"
                style="transform: translate3d(0px, 8px, 0px) scale3d(1, 0.6, 1);"></div>
            <div class="filepond--panel-bottom filepond--panel-root" style="transform: translate3d(0px, 68px, 0px);">
            </div>
        </div><span class="filepond--assistant" ></span>
        <div class="filepond--drip"></div>
    </div>
</div>

我刪去了一些和這個(gè)問題無關(guān)緊要的屬性,可以看出,我們?cè)O(shè)置最大高度的“filepond--root”元素它的高度是由一個(gè)內(nèi)聯(lián)的屬性決定的。而背景的灰色圓角邊框其實(shí)是絕對(duì)定位的“filepond-panel”元素所提供的。由top,center,bottom分別展示頂部圓角邊,中部,底部圓角邊。與此同時(shí),中部元素的css為:

.filepond--panel-center {
    height: 100px !important;
    border-top: none !important;
    border-bottom: none !important;
    border-radius: 0 !important;
}

但是如果我們對(duì)單文件上傳的組件設(shè)置最大高度,初始化組件的時(shí)候就會(huì)根據(jù)多文件組件的方式生成:

異常的上傳框

可以很直觀的看出,中間的元素高度缺失了。但其實(shí)元素和元素的高度還在,只是元素被隱藏了,造成隱藏的css樣式為:

.filepond--panel-center:not([style]) {
    visibility: hidden;
}

這一原因?yàn)楫?dāng)多文件上傳時(shí),標(biāo)簽的dom是包含在panel內(nèi)的,這個(gè)時(shí)候panel的高度是真正的由標(biāo)簽占據(jù),此時(shí)標(biāo)簽是不消失的:

多文件上傳版

單文件版本標(biāo)簽消失:

單文件版

所以如果是否允許多文件上傳的屬性是動(dòng)態(tài)綁定的,就不能把最大高度寫在CSS中!!!

解決方案:

如果不能把樣式固定在<style>中,而class綁定也不會(huì)生效(我試過,會(huì)被覆蓋),那么只能在組件的初始化上下功夫了,借助原生js直接修改樣式表:

//index.vue
<template>
...some code...
    <Filepond @init="handlerInit" />
...some code...
</template>
<script>
...some code
export default{
    mounted:{
        if (allowMultiple) {
        document.styleSheets[0].insertRule('.filepond--root {max-height: 60vh;}', 0);
      }
    }
}
</script>

即可達(dá)成想要的效果。

至于為什么會(huì)設(shè)置高度會(huì)導(dǎo)致DOM預(yù)設(shè)發(fā)生變化,仍在審計(jì)中.....

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前端開發(fā)面試題 面試題目: 根據(jù)你的等級(jí)和職位的變化,入門級(jí)到專家級(jí),廣度和深度都會(huì)有所增加。 題目類型: 理論知...
    怡寶丶閱讀 2,683評(píng)論 0 7
  • 簡介網(wǎng)絡(luò)瀏覽器很可能是使用最廣的軟件。在這篇入門文章中,我將會(huì)介紹它們的幕后工作原理。我們會(huì)了解到,從您在地址欄輸...
    wengjq閱讀 2,312評(píng)論 2 15
  • 前端開發(fā)知識(shí)點(diǎn) HTML&CSS對(duì)Web標(biāo)準(zhǔn)的理解、瀏覽器內(nèi)核差異、兼容性、hack、CSS基本功:布局、盒子模型...
    Hebborn_hb閱讀 896評(píng)論 0 1
  • 一、理論基礎(chǔ)知識(shí)部分 1.1、講講輸入完網(wǎng)址按下回車,到看到網(wǎng)頁這個(gè)過程中發(fā)生了什么 a. 域名解析 b. 發(fā)起T...
    我家媳婦蠢蠢噠閱讀 3,247評(píng)論 2 106
  • 我的一個(gè)工程師同事,業(yè)務(wù)很好,生活是個(gè)白癡。他去女朋友家里時(shí),岳母見他不錯(cuò),第一次登門就給了他許多海鮮,讓他帶回去...
    飛飛魚先生閱讀 2,434評(píng)論 5 43

友情鏈接更多精彩內(nèi)容