Vue 普通对象数据更新与 file 对象数据更新
2017-04-26 10:58
323 查看
最近在做一个多图片上传的组件,需求是做到多文件依次上传,并显示上传进度条。
逻辑部分实现了以后,在更新进度条视图的时候出现一点问题:动态计算生产的进度 progress 属性不会自动更新。
原来的代码是这样写的:
这里直接将 file 对象添加一个 progress 属性记录上传进度,并初始化为0,然后上传时候实时计算更新 progress。但奇怪的是这个 progress 在视图里并不会自动更新,岿然不动,一直都是0。还了N中办法,百思不得其解。
后来一怒之下做了一个小 demo,看看问题到底出现在哪里,把不想关的代码都剔除,只保留核心代码,并用最简单的数据来模拟一下。代码如下:
这里仅仅是把 files 对象换成了数组来模拟,把 file 对象换成了普通对象模拟。
神奇的是,这样居然就自动更新了。
由于文件 file 后来都保存在数组里,这说明唯一的区别就在 file 对象上面!于是打算用普通对象保存 file 对象的属性再试试。
这样视图也是可以自动更新的,果然是 file 对象和普通对象的区别。
它们究竟是什么区别呢?看一下他们的类型先。
原来 files 是 FileList 类型,file 是 File 类型。而普通的 obj 是 Object 类型。
Vue 的数据更新利用的是 Object.defineProperty 的 getter setter 函数来实现的,而 Vue 默认没有对 File 对象设置 getter setter, 因此用 File 对象不会自动更新。
解决办法,就是用普通对象保存 file 对象里需要的信息,然后用来构造视图数据。或者自己手动设置 File 对象的 setter,也可以自动更新。代码如下:
逻辑部分实现了以后,在更新进度条视图的时候出现一点问题:动态计算生产的进度 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,也可以自动更新。代码如下:
<div id="app"> <input type="text" id='a'> <span id='b'></span> <input type="file" id='file'> <button type="button" id='button'>点击更改file属性</button> </div> <script> // 普通对象设置 setter var obj = {}; Object.defineProperty(obj, 'hello', { set: function(newVal) { document.getElementById('a').value = newVal; document.getElementById('b').innerHTML = newVal; } }); document.addEventListener('keyup', function(e){ obj.hello = e.target.value; }); // File 对象设置 setter var fileInput = document.getElementById('file'); var file; fileInput.addEventListener('change', function(e){ file = fileInput.files[0]; Object.defineProperty(file, 'progress', { set: function(newVal) { // document.getElementById('a').value = newVal; document.getElementById('b').innerHTML = newVal; } }); }); document.getElementById('button').addEventListener('click', function(){ file.progress = 'hello file'; }); </script>
相关文章推荐
- 详解Vue 普通对象数据更新与 file 对象数据更新
- Vue 普通对象数据更新与 file 对象数据更新
- vue 循环对象,数据更新,但是视图未刷新
- 设计一个学生类,其中包含学号、姓名、成绩等数据成员,创建学生对象并且倒入到文件file.txt,然后由文件读取到另一个学生对象并输出,试编程实现。
- 用SqlDataAdapter对象更新数据库
- ASP.NET基础教程-使用CommandBuilder对象自动生成SQL语句对数据进行批量更新
- 通过DataSet 对象更新数据库
- 2004-3-27+ 用DataSet对象更新数据
- ArrayCollection更新单个对象数据
- winform 数据绑定 对象的属性,后台异步更新此对象的属性产生异常
- asp.net 用parameter对象更新数据
- linq to sql统一更新方法,直接返回更新的对象(解决更新后再刷新数据错误显示问题)
- 用 DataSet 对象更新数据
- 如何在 Visual C# .NET 中使用 SqlDataAdapter 对象更新 SQL Server 数据库
- java List Collections.sort 排序 支持 对象属性 普通数据类型
- ADO.NET—Asp.net 用DataSet对象更新数据(SqlDataAdapter)
- 用 DataSet 对象更新数据
- [ZT]用 DataSet 对象更新数据
- ASP.NET基础教程-使用CommandBuilder对象自动生成SQL语句对数据进行批量更新
- asp.net 用parameter对象更新数据2011-03-24 22:24asp.net 用parameter对象更新数据