О пользовательском загружаемом файле в элементе, использовании и отказе от el-upload

Element

введение

В нашей повседневной разработке загрузка файлов является очень распространенным требованием. В настоящее время все, кто использует Vue, будут думать об этом.el-uploadЭтот компонент, но в наших нуждах часто необходимо загружать несколько файлов, передавать параметры и т.д. В это время нам нужно использовать егоhttp-requestдля пользовательской загрузки.

Загрузка файлов относительно проста, и вы можете напрямую просмотреть всю часть кода и понять ее с первого взгляда. Запрос на загрузку показан ниже:

image.png

Традиционная форма отправки формы

Существует множество способов загрузки файлов.el-uploadЗагрузка этого компонента — это, по сути, отправка формы, а общая загрузка — это передача двоичных файлов в серверную часть.

image.png

<input type="file" id="upload">
console.log($("#upload").files);  =>  即可拿到一个包含二进制文件的数组。

Однако этот метод не может удовлетворить наши потребности в разработке, на этот раз он может получить только загруженные файлы, и если пользователь добавляет или удаляет файлы или загружает файлы, которые не соответствуют требованиям, нам все равно нужно принимать дальнейшие решения.

upload4.gifТаким образом, мы можем напрямую использовать компонент el-upload, настроить его для загрузки и использовать его уже инкапсулированную функцию ловушки.

Пользовательская загрузка для el-upload

использовать в компонентеhttp-requestЭто свойство, присвоение нашей функции загрузки. восстановить компонентыпри изменении, при удалении, чтобы получить нужный нам файл.

image.png

// 采用form表单的提交方式
let formData = new FormData();
this.upload_List.forEach((item, index) => {
  formData.append("file", FileXX); // 添加文件
});

因为append会添加一个新值到实例对象的一个已存在的键中,如果键不存在则会添加该键。
可以类似理解为=> file : [].push(xxx),所以无论是多个文件一次上传,或单个文件上传都可以使用该方式。

FormData.append()

1. Избегайте ям

В разработке я обнаружил: (1) При удалении файла необработанный файл является объектом, а не файлом. (2) Когда пользователь загружает файл во второй раз,on-changeформальные параметры вfilelistНеобработанный файл второго загруженного файла является объектом, а не файлом. Итак, впри изменении, при удалении, мы не можем напрямую назначить список файлов, но нам нужно добавлять и удалять подэлементы нового массива.

upload2.gif

2. Полный код выглядит следующим образом (включая некоторые суждения)

<el-upload
    id="upload"
    ref="upload"
    drag
    multiple
    :limit="100"
    :file-list="fileList"
    action="#"
    :http-request="Execute_File"
    :auto-upload="false"
    :on-change="upload_change"
    :on-remove="upload_remove"
    :on-exceed="upload_exceed"
    >
    <i class="el-icon-upload"></i>
    <div class="el-upload__text">
      将文件拖到此处,或
      <em>点击选取</em>
    </div>
</el-upload>

data(){
    return {
      fileList: [], //深拷贝,判断重名及第一步时的文件信息展示
      upload_List: [], //上传的file,
      notifyPromise: Promise.resolve() // 解决Notification组件的高度塌陷问题
    };
}

methods:{
    upload_change: function(file, fileList) {
      // 判断 > 1M
      if (file.size > 1048576) {
        fileList.pop();
        let msg_size = `您上传的${file.name},该文件大于1M,请您重新上传。`;
        this.notify_self(msg_size, "size");
        return false;
      }
      // 判断重名文件
      let repeat_judge = this.fileList.find(item => {
        return item.name == file.name;
      });
      if (repeat_judge) {
        fileList.pop();
        let msg_repeat = `您上传的${file.name},该文件有重名文件,请您重新上传。`;
        this.notify_self(msg_repeat, "repeat");
        return false;
      }
      this.fileList = JSON.parse(JSON.stringify(fileList));
      this.upload_List.push(file);
    },
    upload_remove(file, fileList) {
      this.fileList = JSON.parse(JSON.stringify(fileList));
      // 不直接赋值是因为打印出来的数据中,如果多个文件删至只剩一个时,该文件的raw为object,不是file
      this.upload_List.forEach((item, index) => {
        if (item.name == file.name) {
          this.upload_List.splice(index, 1);
        }
      });
    },
    upload_exceed(files, fileList) {
      this.$alert("您最多只能上传100个文件!", "上传文件", {
        confirmButtonText: "确定",
        type: "warning"
      });
    },
    notify_self(msg, type) {
      this.notifyPromise = this.notifyPromise.then(this.$nextTick).then(() => {
        this.$notify({
          title: `${type == "size" ? "文件大于1M" : "文件重名"}`,
          message: msg,
          iconClass: `${
            type == "size" ? "el-icon-s-opportunity" : "el-icon-message-solid"
          }`,
          customClass: `${type == "size" ? "notify_size" : "notify_repeat"}`,
          duration: 6000
        });
      });
    },
    Execute_File() {
        // 传输文件
        let formData = new FormData();
        this.upload_List.forEach((item, index) => {
            formData.append("file", item.raw);
        });
        $.axios({
            url:"XXX",
            method:"post",
            data: formData,
            params:{
                test1:"1",
                test2:"2"
            } //传参
        }).then(res = > { })
          .catch(res = > { })
    },
}

3. Компонент уведомлений. Проблема обрушения высоты компонента

Вставьте отступление ~ При загрузке файла для оценки, если он не соответствует требованиям, мы будем использовать компонент уведомления элемента для подсказки, но этот компонент имеет проблему высокого коллапса.

NG.gif

data(){
    notifyPromise: Promise.resolve()
},

this.notifyPromise = this.notifyPromise.then(this.$nextTick).then(() => {
    this.$notify({
      title: "111111",
      message: "22222",
    });
});

Это решение получено от Baidu, хе-хе,Исходная ссылка на блог: проблема перекрытия уведомлений element-ui, причины и решенияМое понимание заключается в том, чтобы превратить его в процесс синхронного управления путем обещания, получите обновленное состояние DOM через это. $ NextTick и выполните компонент уведомления после обновления DOM.

Эммм правду говорит, я не понял написания вот этого грамматического сахара.В моем понимании вышеописанный способ на самом деле ниже этого процесса, но после того как я переписал, у меня так и не заработало. Если у вас есть старший брат, если вы в беде комментарий, вы будете вести его.

this.notifyPromise = new Promise((resolve, reject) => {
    resolve();
  })
    .then(() => {
      return new Promise((resolve, reject) => {
        this.$nextTick(() => {
          resolve();
        });
      });
    })
    .then(() => {
      this.$notify({
        title: "111111",
        message: "22222"
      });
    });

конечные слова

У хороших людей безопасная жизнь, дайте моему брату большой палец вверх~