解决vue数组中对象属性变化页面不渲染问题

做checkbox多选功能的时候遇到了一个坑,逻辑怎么看都对,但是就是有bug,最后发现数组那里值变了页面勾选没有重新渲染。

换了关键词搜索找到了相关方法。

其实之前读文档教程的时候看到过这里,但是只有真的使用之后才会有最直接的感触。

数组更新检测

变异方法

Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

你打开控制台,然后用前面例子的 items 数组调用变异方法:example1.items.push({ message: 'Baz' }) 。

替换数组

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

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

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

注意事项

由于 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'
})

以上这篇解决vue数组中对象属性变化页面不渲染问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2018-08-06

解决Vue 通过下表修改数组,页面不渲染的问题

需要注意的是,Vue之所以能够监听Model状态的变化,是因为JavaScript语言本身提供了Proxy或者Object.observe()机制来监听对象状态的变化.但是,对于数组元素的赋值,却没有办法直接监听,因此,如果我们直接对数组元素赋值: vm.todos[0] = { name: 'New name', description: 'New description' }; 会导致Vue无法更新View. 正确的方法是不要对数组元素赋值,而是更新: vm.todos[0].name =

Vue 路由切换时页面内容没有重新加载的解决方法

第二次进入页面,页面路由参数已经改变,但是页面内容不会刷新. 问题原因:在组件mounted钩子中调用的刷新页面内容,但测试发现这个钩子没有被调用.后来发现App.vue中使用了<keep-alive>: <template> <div id="app"> <keep-alive> <router-view></router-view> </keep-alive> </div> </t

VUE实现强制渲染,强制更新

列表渲染,以下数组操作方法可触发渲染 push() pop() shift() unshift() splice() sort() reverse() 当采用特殊方法操作数组后,导致无法更新数据到UI,此时可使用强制渲染,方法如下 this.$forceUpdate() 以上这篇VUE实现强制渲染,强制更新就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

解决vue this.$forceUpdate() 处理页面刷新问题(v-for循环值刷新等)

问题描述: 在使用Vue框架开发时,在函数中改变了页面中的某个值,在函数中查看是修改成功了,但在页面中没有及时刷新改变后的值: 解决: 运用 this.$forceUpdate()强制刷新 代码案例 <Select v-model="carSafeLine.insuranceName" placeholder="请选择" class="mulisel option-h" filterable clearable :disabled=&quo

vue修改对象的属性值后页面不重新渲染的实例

最近项目在使用vue,遇到几次修改了对象的属性后,页面并不重新渲染,场景如下: HTML页面如下: <template v-for="item in tableData"> <div :class="{'redBorder':item.red}"> <div>{{ item.name}}</div> <div> <el-button size="mini" @click="

vue 刷新之后 嵌套路由不变 重新渲染页面的方法

解决嵌套路由刷新时,路由没有变化,正常情况下页面是不会重新渲染的 1.在router-view中加上条件渲染 v-if 默认为true.让它显示出来 2.写写一个reload方法,在页面刷新只有,点击某个查询条件的时候调用这个重载的方法 这是条件渲染变化了为false 在修改数据之后使用 $nextTick, 条件渲染变化了为true 则可以在回调中获取更新后的 DOM 如果需要带有查询参数,可以用编程试导航,query来传参,但是这种方式可能刷新之后会有问题. 我的解决方法是在刷新之后点击页面

关于vue2强制刷新,解决页面不会重新渲染的问题

问题描述: 在使用Vue框架开发时,在函数中改变了页面中的某个值,在函数中查看是修改成功了,但在页面中没有及时刷新改变后的值: 解决: 运用 this.$forceUpdate();  //强制刷新,解决页面不会重新渲染的问题 例: <template> <div> <el-card> <ul class="list-style-none title-list"> <li v-for="item in titleList&

解决微信内置浏览器返回上一页强制刷新问题方法

微信内置浏览器在返回上一页面,且上一页面包含AJAX代码时,页面就会被强制刷新,极度影响用户体验.而我们想要的效果是:返回上一页面时,页面还停留在原来的状态,AJAX获取到的数据还在,滚动条也在原来的位置. BINGO~ 通过HTML5的history API + 缓存可以做到这一点. 执行原理: 1.0.通过history API的 history.pushState或 history.replaceState 保存AJAX状态: 2.0.同时将AJAX获取到的数据缓存起来(可以考虑使用H5的

微信web端后退强制刷新功能的实现代码

具体代码如下所示: <script> //生成uuid var uuidChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""); function uuid() { var r; var uuid = []; uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-"; uuid[14] =

Vue-input框checkbox强制刷新问题

在引用input框的checkbox属性时,选中后会出现数据已经刷新,checkbox选中状态不会改变.这时在事件触发后可以调用this.$forceUpdate(),强制刷新页面解决这个问题. input框可以加入readonly="readonly"禁止更改 ps:vue中关于checkbox的问题 在vue中写checkbox时,发现出现问题:当点击一个选项时,输出的数组为空,当取消或者点击下一个选项时,才会出现该选项值且下一个选项值不会出现: <template>

ASP强制刷新网页和判断文件地址实例代码

强制刷新网页 <% '强制性刷新随机验证码 '让随机验证码每次按IE的后退按钮时,返回登录页面的随即码都自动刷新, Response.expires=-1 Response.AddHeader"pragma","no-cache" Response.AddHeader"cache-control","no-store" %> 判断文件地址是否有效 <% Response.Write("")

使用ajax和history.pushState无刷新改变页面URL示例

表现 如果你使用chrome或者firefox等浏览器访问本博客.github.com.plus.google.com等网站时,细心的你会发现页面之间的点击是通过ajax异步请求的,同时页面的URL发生了了改变.并且能够很好的支持浏览器前进和后退. 是什么有这么强大的功能呢? HTML5里引用了新的API,history.pushState和history.replaceState,就是通过这个接口做到无刷新改变页面URL的. 与传统的AJAX的区别 传统的ajax有如下的问题: 1.可以无刷新

使用ajax实现无刷新改变页面内容和地址栏URL

在访问现在很火的google plus时,细心的用户也许会发现页面之间的点击是通过ajax异步请求的,同时页面的URL发生了了改变.并且能够很好的支持浏览器的前进和后退.不禁让人想问,是什么有这么强大的功能呢? HTML5里引用了新的API,就是history.pushState和history.replaceState,就是通过这个接口做到无刷新改变页面URL的. 与传统的AJAX的区别 传统的ajax有如下的问题: 虽然ajax可以无刷新改变页面内容,但无法改变页面URL 其次为了更好的可访

用iframe实现不刷新整个页面上传图片的实例

经常用到上传图片即时预览的功能,实现方式很多,用flash+js实现的比较多,今天遇到同事不想用flash之类也不想用网上的插件,那么我给了他一种解决办法: 思路: 1. 页面上传图片的部分放到一个iframe中,iframe设置无边框无滚动条,和所嵌入的页面风格一致,根据需要设置固定大小 2. 在iframe中提交上传图片的表单,提交后再次返回原页面(iframe所指向的页面)并从服务器带回刚上传的图片地址,调用父页面的js代码加载图片 3. 如果用到要进度条等效果,就在表单提交后,在serv

强制刷新和判断文件地址

复制代码 代码如下: 强制刷新网页<%   '强制性刷新随机验证码  '让随机验证码每次按IE的后退按钮时,返回登录页面的随即码都自动刷新,  Response.expires=-1   Response.AddHeader"pragma","no-cache"   Response.AddHeader"cache-control","no-store"  %> 判断文件地址是否有效 复制代码 代码如下: <

使用pjax实现无刷新更改页面url

我们都知道ajax给浏览器带来了异步加载的能力,在数据校验.局部刷新等方面提升了用户体验,但同时存在如下问题: 1. 可以无刷新改变页面内容,但无法改变页面URL 2. hash的方式不能很好的处理浏览器的前进.后退等问题 为了解决传统ajax带来的问题,HTML5里加强了history API,加入了pushState.replaceState接口和popstate事件.这里就不详细介绍了,没有这方面知识的同学建议先看一下相关的资料. pjax插件封装了pushState和ajax操作,为我们