详解Vue 普通对象数据更新与 file 对象数据更新
最近在做一个多图片上传的组件,需求是做到多文件依次上传,并显示上传进度条。
逻辑部分实现了以后,在更新进度条视图的时候出现一点问题:动态计算生产的进度progress属性不会自动更新。
原来的代码是这样写的:
letfiles=this.filePicker.files; if(!files.length){ return; } letarr=[]; for(leti=0,len=files.length;i这里直接将file对象添加一个progress属性记录上传进度,并初始化为0,然后上传时候实时计算更新progress。但奇怪的是这个progress在视图里并不会自动更新,岿然不动,一直都是0。还了N中办法,百思不得其解。
后来一怒之下做了一个小demo,看看问题到底出现在哪里,把不想关的代码都剔除,只保留核心代码,并用最简单的数据来模拟一下。代码如下:
//用数组模拟files,用对象模拟file对象 letfiles=[]; for(leti=0,len=5;i这里仅仅是把files对象换成了数组来模拟,把file对象换成了普通对象模拟。
神奇的是,这样居然就自动更新了。
由于文件file后来都保存在数组里,这说明唯一的区别就在file对象上面!于是打算用普通对象保存file对象的属性再试试。
letfiles=this.filePicker.files; if(!files.length){ return; } letarr=[]; for(leti=0,len=files.length;i这样视图也是可以自动更新的,果然是file对象和普通对象的区别。
它们究竟是什么区别呢?看一下他们的类型先。
console.log('filestype',Object.prototype.toString.call(files)); //filestype[objectFileList] console.log('arrtype',Object.prototype.toString.call(arr)); //arrtype[objectArray] console.log('itemtype',Object.prototype.toString.call(files[0])); //itemtype[objectFile] console.log('objtype',Object.prototype.toString.call(obj)); //objtype[objectObject]原来files是FileList类型,file是File类型。而普通的obj是Object类型。
Vue的数据更新利用的是Object.defineProperty的gettersetter函数来实现的,而Vue默认没有对File对象设置gettersetter,因此用File对象不会自动更新。
解决办法,就是用普通对象保存file对象里需要的信息,然后用来构造视图数据。或者自己手动设置File对象的setter,也可以自动更新。代码如下:
点击更改file属性
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。