分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

vue多文件上传进度条 进度不更新问题

发布时间:2023-09-06 01:24责任编辑:白小东关键词:文件上传

转自 hhttp://www.cnblogs.com/muge10/p/6767493.html

感谢这位兄弟的文章,之前因为这个问题 ,我连续在sgmentflow上提问过多次,完全没人能回答。谢谢这篇文章

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

逻辑部分实现了以后,在更新进度条视图的时候出现一点问题:动态计算生产的进度 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多文件上传进度条 进度不更新问题

原文地址:http://www.cnblogs.com/ypinchina/p/7827169.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved