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,也可以自动更新。代码如下:
<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 对象数据更新的更多相关文章
- HTML5 File 对象
实例说明1: <div class="container"> <input type="file" id="file" m ...
- File对象的常用方法
File对象不仅可以表示文件,还可以表示目录,源码注释是这么说的:An abstract representation of file and directory pathnames. File类最常 ...
- 用TypeScript开发Vue——如何通过vue实例化对象访问实际ViewModel对象
用TypeScript开发Vue--如何通过vue实例化对象访问实际ViewModel对象 背景 我个人很喜欢TypeScript也很喜欢Vue,但在两者共同使用的时候遇到一个问题. Vue的实例化对 ...
- AIR 中的 File 对象 所访问的文件夹位置
AIR 中的 File 对象 所访问的文件夹位置 Link 关于File.cacheDirectory的一点说明 According to the Apple guidelines, data tha ...
- Python 读写文件和file对象(转)
1.open使用open打开文件后一定要记得调用文件对象的close()方法.比如可以用try/finally语句来确保最后能关闭文件. file_object = open('thefile.txt ...
- 标准I/O库之流和FILE对象
对于标准I/O库,它们的操作是围绕流(stream)进行的.当用标准I/O库打开或创建一个文件时,我们已使一个流与一个文件相关联. 对于ASCII字符集,一个字符用一个字节表示.对于国际字符集,一个字 ...
- 关于Android Assets读取文件为File对象
关于Android Assets读取文件为File对象的问题,在Assets里面放置文件,在使用的时候,一般是使用AssetManger对象,open方法获取InputStream 然后进行其他操作. ...
- 相对路径与绝对路径构造file对象
package file; import java.io.File; public class FileTest1 { public static void main(String[] args) { ...
- VBS基础篇 - 对象(5) - File对象
VBS基础篇 - 对象(5) - File对象 描述:提供对文件所有属性的访问,从FSO对象的GetFile方法获得. 使用File对象 要用File对象模型来编程必须先用FileS ...
随机推荐
- Binary Tree Paths leetcode
Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 ...
- Hibernate优缺点
下面就Hibernate优缺点分别进行简单的阐述.1.Hibernate优点:(1)对象/关系数据库映射(Basic O/R Mapping)它使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的 ...
- 1583: [Usaco2009 Mar]Moon Mooing 哞哞叫
1583: [Usaco2009 Mar]Moon Mooing 哞哞叫 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 244 Solved: 126 ...
- SEO-站外优化规范
站外优化规范 新站 前期(提高网站曝光率<信息发布平台>) 一. 分类目录信息发布 二. 黄页网信息发布 三. 友链平台信息发布 四. 各大论坛引蜘蛛区信息发布 五. 网址提交 六. 社区 ...
- 安装Eclipse(android)新建项目时遇到的问题
---恢复内容开始--- 解决方案: 我先删掉了新建的项目,重新建立项目时 将API都选成相同的API19:... 然后就成功了 ---恢复内容结束---
- 使用Nginx+CppCMS构建高效Web应用服务器
使用Nginx+CppCMS构建高效Web应用服务器 1:Why当前,越来越多的网站使用了各种框架,大部分框架使用了脚本语言.半编译语言等.比如Java.Python.Php.C#.NET等.这些框架 ...
- java线程的等待、通知机制【读书笔记】
代码示例: package com.baidu.nuomi.concurrent; import java.text.SimpleDateFormat; import java.util.Date; ...
- JAVA基础知识(1)
1.JAVA的三大体系:JME(微缩版),JSE(标准版),JEE(企业版): 2.JAVA的三大核心机制:JAVA虚拟机,垃圾回收机制,代码安全性检测 3.java开发集JDK 4.java编译器j ...
- 全新的 flow.ci Dashboard UI 上线
全新的 flow.ci Dashboard 页面上线了,更快捷地创建项目,构建列表页面新增分支,Pull Request 界面:侧边栏新增构建任务监控和项目监控,整个 Dashboard 界面焕然一新 ...
- MFC画笔作用域的问题
今天发现了程序中的一个BUG.功能是在鼠标经过图形时,对图形进行加粗重绘.默认使用白色画刷.为防止白色背景下看不清,在白色背景下改用黑色画刷.代码如下 CPen* pOldPen;if (pDC-&g ...