详解Vue 普通对象数据更新与 file 对象数据更新

网友投稿 336 2023-05-20


详解Vue 普通对象数据更新与 file 对象数据更新

最近在做一个多图片上传的组件,需求是做到多文件依次上传,并显示上传进度条。

逻辑部分实现了以后,在更新进度条视图的时候出现一点问题:动态计算生产的进度 progress 属性不会自动更新。

原来的代码是这样写的:

let files = this.filePicker.files;

if(!files.length) {

return;

}

let arr = [];

for(let i = 0, len = files.length; i < len; i++) {

let item = files[i];

// 每个文件初始进度为0

item.progress = '0';

arr.push(obj);

}

this.fileArr = arr;

这里直接将 file 对象添加一个 progress 属性记录上传进度,并初始化为0,然后上传时候实时计算更新 progress。但奇怪的是这个 progress 在视图里并不会自动更新,岿然不动,一直都是0。还了N中办法,百思不得其解。

后来一怒之下做了一个小 demo,看看问题到底出现在哪里,把不想关的代码都剔除,只保留核心代码,并用最简单的数据来模拟一下。代码如下:

// 用数组模拟 files, 用对象模拟 file 对象

let files = [];

for(let i = 0, len = 5; i < len; i++) {

let obj = {name: 'name_' + 1};

files.push(obj);

}

let arr = [];

for(let i = 0, len = files.length; i < len; i++) {

files[i].progress = '0';

arr.push(files[i]);

}

这里仅仅是把 files 对象换成了数组来模拟,把 file 对象换成了普通对象模拟。

神奇的是,这样居然就自动更新了。

由于文件 file 后来都保存在数组里,这说明唯一的区别就在 file 对象上面!于是打算用普通对象保存 file 对象的属性再试试。

let files = this.filePicker.files;

if(!files.length) {

return;

}

let arr = [];

for(let i = 0, len = files.length; i < len; i++) {

let item = files[i];

let obj = {};

obj.name = item.name;

obj.size = item.size;

obj.progress = '0';

arr.push(obj);

}

这样视图也是可以自动更新的,果然是 file 对象和普通对象的区别。

它们究竟是什么区别呢?看一下他们的类型先。

console.log('files type', Object.prototype.toString.call(files));

// files type [object FileList]

console.log('arr type', Object.prototype.toString.call(arr));

// arr type [object Array]

console.log('item type', Object.prototype.toString.call (files[0]));

// item type [object File]

console.log('obj type', Object.prototype.toString.call (obj));

// obj type [object Object]

原来 files 是 FileList 类型,file 是 File 类型。而普通的 obj 是 Object 类型。

vue 的数据更新利用的是 Object.defineProperty 的 getter setter 函数来实现的,而 Vue 默认没有对 File 对象设置 getter setter, 因此用 File 对象不会自动更新。

解决办法,就是用普通对象保存 file 对象里需要的信息,然后用来构造视图数据。或者自己手动设置 File 对象的 setter,也可以自动更新。代码如下:


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:详解spring+springmvc+mybatis整合注解
下一篇:微信小程序实现给循环列表添加点击样式实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~