SoFunction
Updated on 2025-04-05

Detailed explanation of Vue normal object data update and file object data update

Recently, I am doing a multi-image upload component. The requirement is to upload multiple files in sequence and display the upload progress bar.

After the logic part is implemented, a problem arises when updating the progress bar view: dynamically computed production progress attribute will not be automatically updated.

The original code is written like this:

let files = ;
if(!) {
  return;
}

let arr = [];
for(let i = 0, len = ; i < len; i++) {
  let item = files[i];
  // The initial progress of each file is 0   = '0';

  (obj);
}

 = arr;

Here, add a progress attribute to the file object to record the upload progress and initialize it to 0, and then calculate the update progress in real time during uploading. But strangely, this progress will not be automatically updated in the view, it remains unmoved, and it is always 0. After returning the N-meaning method, I can't figure it out.

Later, I made a small demo in anger to see where the problem really appeared, eliminated all the code I didn't want to close, only retained the core code, and simulated it with the simplest data. The code is as follows:

// Simulate files with arrays, and simulate file objects with objectslet files = [];
for(let i = 0, len = 5; i < len; i++) {
  let obj = {name: 'name_' + 1};

  (obj);
}

let arr = [];
for(let i = 0, len = ; i < len; i++) {
  files[i].progress = '0';
  (files[i]);
}

Here we just replace the files object with an array to simulate, and replace the file object with an ordinary object to simulate.

What's amazing is that it's automatically updated.

Since files are later saved in arrays, the only difference is on the file object! So I plan to use a normal object to save the properties of the file object and try again.

let files = ;
if(!) {
  return;
}


let arr = [];
for(let i = 0, len = ; i < len; i++) {
  let item = files[i];
  let obj = {};

   = ;
   = ;

   = '0';

  (obj);
}

This way the view can also be automatically updated, which is indeed the difference between a file object and a normal object.

What is the difference between them? Take a look at their type first.

('files type', (files));
// files type [object FileList]
('arr  type', (arr));
// arr  type [object Array]

('item type',  (files[0]));
// item type [object File]
('obj type',  (obj));
// obj type [object Object]

It turns out that files is FileList type, and file is File type. And ordinary obj is the Object type.

Vue's data update uses the getter setter function to implement it. Vue does not set getter setter for File objects by default, so the File object will not be automatically updated.

The solution is to use ordinary objects to save the information needed in the file object and then use it to construct view data. Or manually set the setter of the File object by yourself, and it can also be updated automatically. The code is as follows:

&lt;div &gt;
  &lt;input type="text" id='a'&gt;
  &lt;span id='b'&gt;&lt;/span&gt;

  &lt;input type="file" id='file'&gt;
  &lt;button type="button" id='button'&gt;Click Changefileproperty&lt;/button&gt;
&lt;/div&gt;

&lt;script&gt;
  // Setting setter for normal object  var obj = {};
  (obj, 'hello', {
    set: function(newVal) {
      ('a').value = newVal;
      ('b').innerHTML = newVal;
    }
  });

  ('keyup', function(e){
     = ;
  });

  // File object setting setter  var fileInput = ('file');
  var file;
  ('change', function(e){
    file = [0];

    (file, 'progress', {
      set: function(newVal) {
        // ('a').value = newVal;
        ('b').innerHTML = newVal;
      }
    });
  });

  ('button').addEventListener('click', function(){
     = 'hello file';
  });

&lt;/script&gt;

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.