详解Vue 普通对象数据更新与 file 对象数据更新
发布时间 - 2026-01-11 00:51:19 点击率:次最近在做一个多图片上传的组件,需求是做到多文件依次上传,并显示上传进度条。

逻辑部分实现了以后,在更新进度条视图的时候出现一点问题:动态计算生产的进度 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
# 数据更新
# vue.js
# 更新对象
# vue数据更新UI不刷新显示的解决办法
# 解决echarts vue数据更新
# 视图不更新问题(echarts嵌在vue弹框中)
# 详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结
# vue 解决异步数据更新问题
# Vue.js中provide/inject实现响应式数据更新的方法示例
# 详解vue中的父子传值双向绑定及数据更新问题
# 解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题
# 解决vue keep-alive 数据更新的问题
# 谈谈对vue响应式数据更新的误解
# vue+echarts实现数据实时更新
# 的是
# 上传
# 自动更新
# 可以自动
# 换成了
# 都是
# 进度条
# 他们的
# 岿然不动
# 就在
# 是这样
# 出现在
# 百思不得其解
# 仅仅是
# 做一个
# 看一下
# 多图
# 最简单
# 来实现
# 解决办法
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)
如何快速生成专业多端适配建站电话?
Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】
如何在万网开始建站?分步指南解析
Laravel如何实现事件和监听器?(Event & Listener实战)
JavaScript Ajax实现异步通信
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
Laravel安装步骤详细教程_Laravel环境搭建指南
如何在宝塔面板中创建新站点?
历史网站制作软件,华为如何找回被删除的网站?
太平洋网站制作公司,网络用语太平洋是什么意思?
如何在云服务器上快速搭建个人网站?
Laravel如何使用Passport实现OAuth2?(完整配置步骤)
高端企业智能建站程序:SEO优化与响应式模板定制开发
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
使用Dockerfile构建java web环境
iOS验证手机号的正则表达式
Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?
Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程
DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解
PHP正则匹配日期和时间(时间戳转换)的实例代码
利用vue写todolist单页应用
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
Laravel如何使用Service Container和依赖注入?(代码示例)
Linux系统命令中screen命令详解
JavaScript如何操作视频_媒体API怎么控制播放
Laravel怎么清理缓存_Laravel optimize clear命令详解
js实现获取鼠标当前的位置
Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】
Python3.6正式版新特性预览
详解MySQL数据库的安装与密码配置
Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】
Laravel如何实现API版本控制_Laravel版本化API设计方案
🚀拖拽式CMS建站能否实现高效与个性化并存?
Laravel如何实现用户密码重置功能?(完整流程代码)
详解阿里云nginx服务器多站点的配置
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
Laravel Fortify是什么,和Jetstream有什么关系
Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
移动端脚本框架Hammer.js
Android自定义listview布局实现上拉加载下拉刷新功能
奇安信“盘古石”团队突破 iOS 26.1 提权
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
成都网站制作公司哪家好,四川省职工服务网是做什么用?
C语言设计一个闪闪的圣诞树
HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】
网站制作软件有哪些,制图软件有哪些?
如何在阿里云香港服务器快速搭建网站?

