最近使用vue开发时,在一个函数中使用for循环,改变了页面中的数组,在函数中查看是修改成功的,但是页面中没有动态刷新。

在Vue的官方文档有提到这样一个注意事项:

数组变更检测注意事项:

由于 JavaScript 的限制,Vue 不能检测以下数组的变动:

当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue

当你修改数组的长度时,例如:vm.items.length = newLength

举个例子:

var vm = newVue({

data: {

items: ['a', 'b', 'c']

}

})

vm.items[1] = 'x' //不是响应性的

vm.items.length = 2 //不是响应性的

也就是说,直接设置数组的某一项的值,虽然改变了数组的值,但视图上显示的仍为数组之前的值,数据的响应失效了。出现这种现象的根本原因是什么呢?

首先我们先来了解vue数据响应的原理。官方文档的解释:

当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。

也就是说当改变data中属性的值时会触发其相应setter的调用,从而实现响应的操作。但getter和setter是有局限性的。我们先来看下面的这个例子:

var person ={};

Object.defineProperties( person, {

age: {

defaultValue:11,

get:function() {return this.defaultValue;

},

set:function(val) {this.defaultValue =val;

console.log("触发了set")

}

}

});//修改属性的值时能够触发set

person.age = 12 //触发了set

->触发了set->12person.age->12

//将属性的值设置为一个数组,当通过索引值修改数组的某一项或使用数组的某些方法修改数组时不能触发set

person.age = [2,3,4] //触发了set

->触发了set->(3) [2, 3, 4]

person.age[2] = 5 //未触发set

->5person.age->(3) [2, 3, 5]

person.age.push(5) //未触发set

->4person.age->(4) [2, 3, 4, 5]//将属性的值设置为一个对象,当修改对象中某属性的值时无法触发set

person.age = { first: 1}->触发了set->{first: 1}

person.age.first= 2 //未触发set

->2

通过上述例子可以观察得出:

当该属性的值为一个数组时,通过索引修改数组某一项的值或使用数组的某些方法修改数组并不能触发set;当属性的值为一对象时,直接修改对象中属性的值时也无法触发set。

为了解决当你利用索引直接设置一个数组项问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将在响应式系统内触发状态更新:

//Vue.set

Vue.set(vm.items, indexOfItem, newValue)

//Array.prototype.splice

vm.items.splice(indexOfItem, 1, newValue)

你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:

vm.$set(vm.items, indexOfItem, newValue)

为了解决当你修改数组的长度问题,你可以使用 splice:

vm.items.splice(newLength)

对象变更检测注意事项:

还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:

var vm = newVue({

data: {

a:1}

})//`vm.a` 现在是响应式的

vm.b= 2

//`vm.b` 不是响应式的

对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。例如,对于:

var vm = newVue({

data: {

userProfile: {

name:'Anika'}

}

})

当修改对象的属性或为对象添加属性时,应该使用以下方法:

Vue.set(vm.userProfile, 'age', 27)

或者

vm.$set(vm.userProfile, 'age', 27)

有时你可能需要为已有对象赋值多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:

Object.assign(vm.userProfile, {

age:27,

favoriteColor:'Vue Green'})

你应该这样做:

vm.userProfile = Object.assign({}, vm.userProfile, {

age: 27,

favoriteColor: 'Vue Green'

})

由于数据响应原理机制, Vue 不允许动态添加根级响应式属性,所以你必须在初始化实例前声明所有可能用到的根级响应式属性,且为这些属性都设一个初值,哪怕只是一个空值。

回归正题,我项目中遇到的这个问题,解决方法:

1. 运用this.$forceUpdate()强制刷新。

2. 使用vm.$set(vm.items, indexOfItem, newValue)

eg.  vm.$set(vm.dataList[i],  picUrl, 'data:image/jpg;base64,' + response.data)

export default{

data() {return{

dataList:[],

};

},

methods: {

getData() {var _this = this;var dataList =[];

dataList=response.data.data;for(var i=0;i

_this.downloadBase64(dataList[i].fielID, i, dataList);

}

},

downloadBase64(fielID, i, dataList) {var vm = this;

$.ajax({

url: AppInter.downloadBase64,

asysc:true,

data: {

fileName:'1.jpg',

fileId: fielID

},

cache:!0,

timeout:2e4,

dataType:"json",

type:"POST",

xhrFields: {

withCredentials:!0},

crossDomain:!0,

contentType:"application/x-www-form-urlencoded;charset=UTF-8",

beforeSend:function() {

vm.loading=weui.loading();

},

success:function(response) {if (response.responseCode == '0') {

dataList[i].picUrl= 'data:image/jpg;base64,' + response.data;

vm.dataList =dataList;

vm.$forceUpdate();

}else{

weui.alert("请求错误,请稍候再试", function() {}, {

title:'温馨提示'});

}

},

error:function(xhr, msg, err) {

weui.alert("请求失败,请稍候再试", function() {}, {

title:'温馨提示'});

},

complete:function() {if(vm.loading.hide) {

vm.loading.hide();

}

}

})

}

},

created() {

},

mounted() {

}

};

vue数组刷新_Vue中数组更新后,页面没有动态刷新问题相关推荐

  1. 微信开发者工具:代码更新后页面未刷新

    问题 微信开发者工具代码更新后页面未更新.只用通过手动点击编译才可更新页面 尝试过稳定版 16.15 版本均未解决 开发环境 项目配置:Taro3 + React17 + Node18 + @antm ...

  2. vue数组刷新_Vue数组更新方法

    Vue的核心是数据与视图的双向绑定,当我们修改数组时,Vue会检测到数据变化,所以用v-for渲染的视图也会立即更新.Vue包含了一组观察数组变异的方法,使用他们改变数组也会触发视图更新. push( ...

  3. c语言变量定义数组,C语言中数组的定义和使用

    一.1.一维数组的定义: 类型说明符 数组名[常量表达式];    注意:常量表达式包括常量与符号常量,不能包含变量. 2.一维数组的引用: 数组名[下标]; 3.一维数组的初始化: a.在定义数组时 ...

  4. 数组方法 + ES6中数组方法 + 数组的空位

    目录 1.静态方法 1.Array.isArray() Array.isArray方法返回一个布尔值,表示参数是否为数组.它可以弥补typeof运算符的不足. 2.Array.from() 用于将两类 ...

  5. perl 数组引用_Perl中数组引用的魔力

    perl 数组引用 在编程世界中,如果不遇到嵌套的数据结构,您将走得很远. 例如,JavaScript对象可能如下所示: var cats = { "name":"Mr. ...

  6. java 数组 内存_Java 中数组的内存分配

    Java 中数组的内存分配 1.Java 程序在运行时,需要在内存中分配空间.为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据和内存管理方式. 2.数组基本概念 数组是 ...

  7. java 数组参数_java中 数组可以作为形式参数传递到调用的方法中吗?要怎么操作?...

    展开全部 可以,操作代码如下: public class ArrTest{ public static void doTest(String[] args){ for(int i=0;i System ...

  8. swift语言 数组定义_Swift3中数组创建方法

    转载自:http://blog.csdn.net/bwf_erg/article/details/70858865 数组是由一组类型相同的元素构成的有序数据集合.数组中的集合元素是有 序的,而且可以重 ...

  9. php中不让数组初始化,javascript中数组与php数组初始化差异

    准确来说,javascript中我们需要称之为数组对象,因为数组就是对象,不信你看: var a=[1,2,3]; //竟然会弹出object alert(typeof(a)); 之前学习php的时候 ...

最新文章

  1. 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
  2. [云炬创业基础笔记]第七章创业资源测试7
  3. mysql源码启动_Mysql源码安装、配置、初始化及启动
  4. MySQL的内置函数
  5. < meta name=“viewport“ content=“width=device-width, initial-scale=1.0“>的解释
  6. ZUI – 开源HTML5跨屏框架
  7. Quartz调度源码分析
  8. 为什么无法建立过程性能模型?
  9. tensorflow随笔——交叉熵公式推导
  10. Socket编程--TCP服务端注意事项
  11. 第1章 《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)周志明》目录
  12. 体脂的计算Java_简单测试体脂率的两种经验公式
  13. am3352 项目记录
  14. Asp.net 企业建站CMS
  15. See Electrical 7 R2 B11电气设计软件PLS-CADD v12.3架空电力线设计软件
  16. php推送消息到邮箱,thinkphp3.2通过PHPMailer发送邮件推送消息
  17. building workspace问题
  18. Hadoop的安装与配置(非常重要)
  19. Python深度学习与机器视觉(一)
  20. 『 kaggle』kaggle-DATA-SCIENCE-BOWL-2018(U-net方法)

热门文章

  1. SLF4J with Logback in a Maven Project | Mograblog
  2. hdu 5631 Rikka with Graph(图)
  3. unity, 相机空间 与 相机gameObject的局部空间
  4. netapp存储常用命令
  5. ActiveBpel部署运行BPEL流程实例
  6. mfc文字闪烁如何解决_男同胞福音!如何解决尿尿时最尴尬的难题?建议偷偷收藏(文字版)...
  7. chkconfig: 2345 20 80
  8. java 数据库连接 释放_java - 数据库连接池耗尽 - Java - 堆栈内存溢出
  9. [转载] Python 迭代器 深入理解 与应用示例
  10. python 改变词典顺序_按词典顺序排列的功率集