版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
版权
我们都知道,vue的特点之一就是数据驱动视图,也就是当我们的数据发生改变的时候,视图也就随之改变了,不需要我们再进行更新视图的操作,但是有一些情况,我们虽然改变了数据,但是视图并没有变化,官网是这样解释的:由于 JavaScript 的限制,Vue 不能检测数组和对象的变化,其实我认为应该说vue不能检测未挂载的即后来添加的新属性,所以需要我们进行一些操作达到我们想让vue检测的目的
对于对象
Vue.set()
通过代码展示:
Document{{show}}添加b
const vm = new Vue({ el: "#app", data(){ return{ show:{ a:"我是a" } } }, methods: { add() { this.show.b = "我是b" console.log(this.show) } } })
效果:
当我们点击按钮的时候,我们可以发现show里边确实添加了b属性,但是视图并没有展示。如果我们想要展示就需要用到vue提供的一个方法Vue.set(),如果我们改变添加方式:
methods: { add() { Vue.set(this.show,"b",2) console.log(this.show) } }
效果:
此时,我们点击按钮,视图发生了改变,当然,data内的show对象也添加了b属性
Object.assign() 或_.extend()
官网上是这样说的:有时你可能需要为已有对象赋值多个新 property,比如使用 Object.assign() 或_.extend()。但是,这样添加到对象上的新 property 不会触发更新。在这种情况下,你应该用原对象与要混合进去的对象的 property 一起创建一个新的对象。
我们还是通过代码理解:
methods: { add() { this.show = Object.assign({},this.show,{b:1,c:"我是c"}) console.log(this.show) } }
分析:Object.assign()是合并对象的意思,Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。代码的意思是我们把原来的对象和新增属性组成的对象,合并到一个空对象里边{},这时候相当于给我们data里边的show重新赋值;(_.extend()也是合并的一种方式)
效果:
对于数组
Vue 不能检测以下数组的变动:
当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue当你修改数组的长度时,例如:vm.items.length = newLength
那我们怎么改变数组已经定义好的元素呢?
方法一:变更方法(这种都是修改原数组)
就拿我们通过索引来修改原数组
代码举例:
Document{{arr}}点击
const app = new Vue({ el: "#app", data: { arr: [1, 2] }, methods: { btn() { this.arr[2] = 3 console.log(this.arr) } } })
效果:
跟改变对象属性很类似,那个是用到了Vue.set方法,在数组里边我们就要用可以引起视图发生改变的方法。
push()pop()shift()unshift()splice()sort()reverse()
还是那个例子,我们就可以用数组的splice或者push进行添加操作
methods: { btn() { this.arr.splice(2,1,3) //或者push // this.arr.push(3) console.log(this.arr) } }
效果:
替换数组
官方解释:变更方法,顾名思义,会变更调用了这些方法的原始数组。相比之下,也有非变更方法,例如 filter()、concat() 和slice()。它们不会变更原始数组,而总是返回一个新数组。当使用非变更方法时,可以用新数组替换旧数组:
解释:比如filter()方法,我们进行筛选过后,并不会改变原数组,而是返回一个新数组,我们再把新数组赋值给一个已经定义好的数组来保存就可以(有点类似,对象使用的方法Object.assign()方法,空对象,把需要的总的数据放到空对象里边,再把这个新对象赋值给定义好的对象)
代码举例:
const app = new Vue({ el: "#app", data: { arr: [1, 2, 5, 6, 8], }, methods: { btn() { this.arr = this.arr.filter(item => { return item > 3 }) console.log(this.arr) } } })