问题引入

Vue之所以能够监听Model状态的变化,是因为JavaScript语言本身提供了Proxy或者Object.observe()机制来监听对象状态的变化。但是,对于数组元素的赋值,却没有办法直接监听。

因此,如果我们直接对数组元素赋值

<ul>
<li v-for="(item,index) in arrInfo">{{item.name}}--{{item.age}}</li>
</ul>
data(){
return {
arrInfo:[
{'name':'zuobaiquan','age':22},
{'name':'zhangsan','age':20}
]
}
},
// created(){
// this.arrInfo[0]={'name':'zuobaiquan01','age':22}
// },
mounted(){
this.arrInfo[0]={'name':'zuobaiquan02','age':22}
}

在mounted阶段,直接对数组元素 arrInfo 赋值会导致Vue无法更新View

说明:在 created 视图未渲染时 直接对数组元素 arrInfo 赋值 data里面的初值会改变的。

此时在mounted阶段,简单的做法是不要对数组元素赋值,而是更新

mounted(){
this.arrInfo[0]={'name':'zuobaiquan02','age':22}
//正确做法
//this.arrInfo[0].name='zuobaiquan02'
//this.arrInfo[0].age=23
}

另一种做法:通过splice()方法,删除某个元素后,再添加一个元素,达到“赋值”的效果:

//正确做法二 通过splice()方法,删除某个元素后,再添加一个元素,达到“赋值”的效果:
var newArrItem={'name':'zuobaiquan02','age':24}
this.arrInfo.splice(0, 1, newArrItem); 

源码地址:https://github.com/zuobaiquan/vue/blob/master/vueExercise/vue-test/src/views/vue-set/index01.vue

针对此问题 vue还提供了另外一种方法 set   https://cn.vuejs.org/v2/api/#vm-set

调用方法:Vue.set( target, key, value )

target:要更改的数据源(可以是对象或者数组)

key:要更改的具体数据

value :重新赋的值

此时 应该这样处理

//正确做法三 利用vue内置属性 set
var newArrItem={'name':'zuobaiquan02','age':24}
this.$set(this.arrInfo,0,newArrItem)

数组更新检测

变异方法

Vue 包含一组监听数组的变异方法,所以它们也将会触发视图更新。这些方法有 push、pop、shift、unshift、splice、sort、reverse

替换数组

变异方法 (mutation method),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异 (non-mutating method) 方法,例如:filter()concat() 和 slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:

example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})

你可能认为这将导致 vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的、启发式的方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

整理:变异方法:push、pop、shift、unshift、splice、sort、reverse

非变异方法:filter、 concat、 slice

总结

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

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

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

为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)

或者

// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)

为了解决第二类问题,你可以使用 splice

example1.items.splice(newLength)

对象更改检测注意事项

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

var vm = new Vue({
data: {
a: 1
}
})
// `vm.a` 现在是响应式的 vm.b = 2
// `vm.b` 不是响应式的

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

var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})

你可以添加一个新的 age 属性到嵌套的 userProfile 对象:

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

你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:

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

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

Object.assign(this.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})

你应该这样做:

this.userProfile = Object.assign({}, this.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})

参考原文:https://www.cnblogs.com/thinkingthigh/p/7789108.html

vue数组中对象属性变化页面不渲染问题的更多相关文章

  1. Vue 数组中更新属性值后,视图不更新,等待其他元素更新后会触发的解决办法

    因为 JavaScript 的限制,Vue.js 不能检测到下面数组变化: 直接用索引设置元素,如 vm.items[0] = {}: 修改数据的长度,如 vm.items.length = 0. t ...

  2. vue动态添加对象属性,视图不渲染

    发现数据确实改变了.但是视图没有渲染.原因是赋值的问题,应该这样动态增加属性 vm.$set(vm.template.titleAttachInfoDetail,newKey,newVal) vm 当 ...

  3. vue监听数组中某个属性,计算其他属性问题

    今天在项目开发中遇到一个根据数组中某个属性变化同时更新另一个属性变化的问题,刚开始代码如下 this.weekList1=r.data.roomProducts; this.weekList1.map ...

  4. vue 数组中嵌套的对象添加新属性--页面更新

    vue 数组中嵌套的对象添加新属性--页面更新:https://www.jianshu.com/p/8f0e5bb13735

  5. Vue 改变数组中对象的属性不重新渲染View的解决方案

    Vue 改变数组中对象的属性不重新渲染View的解决方案 在解决问题之前,我们先来了解下 vue响应性原理: Vue最显著的一个功能是响应系统-- 模型只是一个普通对象,修改对象则会更新视图.受到ja ...

  6. js sort方法根据数组中对象的某一个属性值进行排序(实用方法)

    js sort方法根据数组中对象的某一个属性值进行排序 sort方法接收一个函数作为参数,这里嵌套一层函数用来接收对象属性名,其他部分代码与正常使用sort方法相同. var arr = [ {nam ...

  7. array排序(按数组中对象的属性进行排序)

    使用array.sort()对数组中对象的属性进行排序 <template> <div> <a @click="sortArray()">降序& ...

  8. 仵航说 Vue用replace修改数组中对象的键值或者字段名 仵老大

    仵航说 Vue用replace修改数组中对象的键值或者字段名 仵老大 1.介绍 先看图 ​ 今天在项目中遇到了一个问题,例如我现在需要传一些数据到后端,数组例如是 let arr = [ {" ...

  9. vue 数组和对象渲染问题

    vue 数组和对象渲染问题 最近项目有点忙碌,遇到好多问题都没有总结(╥﹏╥),在开发过程中,取vuex中的数组渲染完成之后,再次修改数组的值,数据更新了,但是视图并没有更新.以为是数组更新的问题,后 ...

随机推荐

  1. mininet安装过程记录

    参考文档: http://www.brianlinkletter.com/set-up-mininet/ https://github.com/mininet/mininet/wiki/FAQ#x11 ...

  2. Python常用模块:datetime

    使用前提: >>> from datetime import datetime 常见用法: 1.获取当前日期和时间 >>> now = datetime.now() ...

  3. IDEA修改Git账户和密码

    找到c盘中git目录的.gitconfig文件可以直接修改name和邮箱   

  4. [20190401]跟踪dbms_lock.sleep调用.txt

    [20190401]跟踪dbms_lock.sleep调用.txt --//自己在semtimedop函数调用理解错误,加深理解,跟踪dbms_lock.sleep调用的情况. 1.环境:SCOTT@ ...

  5. SQLServer之创建表值函数

    表值函数创建注意事项 用户定义表值函数返回 table 数据类型. 对于内联表值函数,没有函数主体,表是单个 SELECT 语句的结果集. 表值函数主要用于数据计算出来返回结果集. 使用SSMS数据库 ...

  6. Expression

    表达式目录树 1.什么是表达式目录树Expression? 表达式目录树是一个数据结构,语法树. 首先我们去看看 Expressions类 ,定义了一个泛型委托类型 TDelegate: // 摘要: ...

  7. 【Eclipse】springMVC介绍与配置

    SpringMCV介绍: Spring MVC是一种基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动的,也就是使用 ...

  8. javascript Json和String互转

      var jsonText = "{\"id\":\"123\",\"name\":\"tom\",\&qu ...

  9. 关于opencv模板匹配功能的项目测试记录

    模板匹配功能介绍的很好的一篇博客:https://www.cnblogs.com/XJT2018/p/9934139.html 就如上述博客所言:“若原图像中的匹配目标发生旋转或大小变化,该算法无效. ...

  10. elasticsearch系列八:ES 集群管理(集群规划、集群搭建、集群管理)

    一.集群规划 搭建一个集群我们需要考虑如下几个问题: 1. 我们需要多大规模的集群? 2. 集群中的节点角色如何分配? 3. 如何避免脑裂问题? 4. 索引应该设置多少个分片? 5. 分片应该设置几个 ...