Vue不能检测到Object/Array更新的情况的解决

前言

看文档不认真,开发也没有多注意,总是hack。忽悠忽悠就过去,但怎么说,歪门邪道还是不太好,现在就亡羊补牢,总结总结。

数组

索引

  1. 使用下标更新数组元素;
  2. 使用赋值方式改变数组长度;
  3. 使用下标增删数组元素;

正文

使用下标更新数组元素

data: {
  arrs: [0, 1, 2, 3]
}

直接使用this.arrs[0] = 'zero';虽然数组确实是被更新了,但是更新不会被渲染到视图(html页面)上。因为Vue没有检测到数组的更新。

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

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

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

官方应对方法:

1、Vue.set( target, key, value )

Vue.set(this.arrs, 0, 'zero');

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

this.arrs.splice(0, 1, 'zero');

使用赋值方式改变数组长度

即this.arrs.length = 100;无效!

官方应对方法:

1、vm.items.splice(newLength)

this.arrs.splice(100);

使用下标增删数组元素

即一下操作无效:

this.arrs[this.arrs.length] = this.arrs.length;

官方应对方法:变异方法。

  1. push()
  2. pop()
  3. shift()
  4. unshift()
  5. splice()
  6. sort()
  7. reverse()
this.arrs.push(this.arrs.length);

8、替换数组(改变引用)

如官方所言:filter(), concat() 和 slice()都是会返回一个新数组

this.arrs = this.arrs.contact(this.arrs.length);
// or
// this.arrs = this.arrs.contact([this.arrs.length]);

官方对性能问题的回应:

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

对象

索引

增删元素;

正文

data: {
 foo: { name: 'isaac' }
}

增删元素

this.foo.job = 'coder';
delete this.foo.name;

如上增删元素是无效的。

官方的解决方法:

// 新增
Vue.set(this.foo, 'job', 'coder');

// 删除
Vue.delete(this.foo, 'name');

Vue.delete对数组也是有效传送门

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue.js中$set与数组更新方法

    由于 JavaScript 的限制,Vue 不能检测以下变动的数组: 当利用索引直接设置数组的某一项时,例如:vm.items[indexOfItem] = newValue 当你修改数组的长度时,例如:vm.items.length = newLength,不会更新数组. 当然vue中给了解决方法,就是使用 Vue.set, vm.$set(Vue.set的变种写法)或者 splice,caoncat等修改数组,同时也将触发状态更新: ex: 所以如果在实例创建后添加新的属性到实例上,则不会触

  • Vue数组更新及过滤排序功能

    前面的话 Vue为了增加列表渲染的功能,增加了一组观察数组的方法,而且可以显示一个数组的过滤或排序的副本.本文将详细介绍Vue数组更新及过滤排序 变异方法 Vue 包含一组观察数组的变异方法,它们将会触发视图更新,包含以下方法 push() 接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度 pop() 从数组末尾移除最后一项,减少数组的length值,然后返回移除的项 shift() 移除数组中的第一个项并返回该项,同时数组的长度减1 unshift() 在数组前端添加任意个

  • 解决vue中对象属性改变视图不更新的问题

    常规情况下我们在vue实例的data中设置响应数据.但当数据为对象,我们增加或删除对象属性值时,视图并不触发更新,如何解决这个问题呢? 实例代码如下: let vm = new Vue{ el: '#app', data: { obj: { k: 'v' } }, ... } 有三种解决方案: 方案一:利用Vue.set(object,key,val) 例:Vue.set(vm.obj,'k1','v1') 方案二:利用this.$set(this.obj,key,val) 例:this.$se

  • vue.js移动数组位置,同时更新视图的方法

    使用vue.js v-for绑定若干个选项,需要对选项进行排序上下移动操作. 需要对options里面数组的位置进行交换,通常是这样来写: 假设向前移动一个: var index = this.options.indexOf(option); //获取当前选项对象在数组里面的索引. var tempOption = this.options[index-1]; //存储前一个 this.options[index-1] = option;(this.options[index]) this.op

  • 详解VUE 数组更新

    1.数据方法分类: (1)原数组改变 push  pop  unshift  shift  reverse  sort  splice (2)原数组未变,生成新数组 slice  concat  filter 对于使原数组变化的方法,可以直接更新视图. 对于原数组未变的方法,可以使用新数组替换原来的数组,以使视图发生变化. 示例代码: <!DOCTYPE html> <html lang="zh"> <head> <meta charset=&

  • 详解Vue 普通对象数据更新与 file 对象数据更新

    最近在做一个多图片上传的组件,需求是做到多文件依次上传,并显示上传进度条. 逻辑部分实现了以后,在更新进度条视图的时候出现一点问题:动态计算生产的进度 progress 属性不会自动更新. 原来的代码是这样写的: let files = this.filePicker.files; if(!files.length) { return; } let arr = []; for(let i = 0, len = files.length; i < len; i++) { let item = fi

  • Vue不能检测到Object/Array更新的情况的解决

    前言 看文档不认真,开发也没有多注意,总是hack.忽悠忽悠就过去,但怎么说,歪门邪道还是不太好,现在就亡羊补牢,总结总结. 数组 索引 使用下标更新数组元素: 使用赋值方式改变数组长度: 使用下标增删数组元素: 正文 使用下标更新数组元素 data: { arrs: [0, 1, 2, 3] } 直接使用this.arrs[0] = 'zero';虽然数组确实是被更新了,但是更新不会被渲染到视图(html页面)上.因为Vue没有检测到数组的更新. 由于 JavaScript 的限制,Vue 不

  • Vue不能检测到数据变化的几种情况说明

    目录 Vue不能检测到数据变化的情况 第一类:对于数组 第二类:对于对象 Vue检测数据的原理 总结一下 Vue不能检测到数据变化的情况 Vue 实现了数据的双向绑定,所以我们在更改数据时,页面就会实时的反映出修改的变化 但是由于javascript 的限制,有几种情况,vue是不能检测到数据变化的 第一类:对于数组 1. 当你利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue 2. 当你修改数组的长度时,例如: vm.items.length =

  • 解决Vue不能检测数组或对象变动的问题

    来看一个实例: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script> <style> li:hover

  • 详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结

    如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事. 1. Vue 无法检测实例被创建时不存在于 data 中的 property 原因:由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的. 场景: var vm = new Vue({ data:{}, // 页面不会变化 template: '<div>{{message}

  • VUE异步更新DOM - 用$nextTick解决DOM视图的问题

    VUE异步更新DOM 首先,Vue 在更新 DOM 时是异步执行的! 所以只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更.如果同一个 watcher 被多次触发,只会被推入到队列中一次.这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的.然后,在下一个的事件循环"tick"中,Vue 刷新队列并执行实际 (已去重的) 工作.Vue 在内部对异步队列尝试使用原生的 Promise.then.MutationObserver 和

  • 解决vue中修改了数据但视图无法更新的情况

    我们有时候常碰到vue中明明修改了数据,但是视图无法更新,因此我总结了一点点碰到此类的情况: 1.v-for遍历的数组,当数组内容使用的是arr[0].xx =xx更改数据,vue无法监测到 数组数据变动:我们使用某些方法操作数组,变动数据时,有些方法无法被vue监测,有些可以 Vue包装了数个数组操作函数,使用这些方法操作的数组去,其数据变动时会被vue监测: push() pop() shift() unshift() splice() sort() reverse() vue2.0还增加个

  • vue源码之批量异步更新策略的深入解析

    vue异步更新源码中会有涉及事件循环.宏任务.微任务的概念,所以先了解一下这几个概念. 一.事件循环.宏任务.微任务 1.事件循环Event Loop:浏览器为了协调事件处理.脚本执行.网络请求和渲染等任务而定制的工作机制. 2.宏任务Task: 代表一个个离散的.独立的工作单位.浏览器完成一个宏任务,在下一个宏任务开始执行之前,会对页面重新渲染.主要包括创建文档对象.解析HTML.执行主线JS代码以及各种事件如页面加载.输入.网络事件和定时器等. 3.微任务:微任务是更小的任务,是在当前宏任务

  • Vue 对象和数据的强制更新方式

    目录 对象和数据的强制更新 数组更新 强制更新 更新数据并强制更新视图 对象类型 数组类型 异步类型 强制更新 对象和数据的强制更新 数组更新 以下支持自动更新 push() //向后添加 pop() //删除最后一个 shift() //删除第一个 unshift() //向第一个添加元素 splice() //向指定位置添加/删除元素 sort() //用原地算法对数组的元素进行排序 reverse() //将数组中元素的位置颠倒 注意,这种形式修改数据 this.arr[1] = ‘x’

  • JS深度拷贝Object Array实例分析

    本文实例分析了JS深度拷贝Object Array.分享给大家供大家参考,具体如下: function cloneObj(o) { var isArray = o instanceof Array; var isObject = o instanceof Object; if (!isObject) return o; var n = (isArray ? [] : {}); for (var k in o) n[k] = cloneObj(o[k]); return n; } 遇到的问题 ty

随机推荐