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

Vue 实现了数据的双向绑定, 所以我们在更改数据时, 页面就会实时的反映出修改的变化 但是由于javascript 的限制, 有几种情况, vue是不能检测到数据变化的

第一类, 对于数组,

  1. 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength 如下例
new Vue({
          
   
		data(){
          
   
			return {
          
   
				arr:[
					{
          
   id:1,name:"haha",age:18},
					{
          
   id:2,name:"hehe",age:19}
				]
			}
		}
	})
	......
	methods:{
          
   
		change(){
          
   
			this.arr[0] = {
          
   id:1,name:"gege",age:30};  //这种写法vue是不能检测到的, 也就是说页面的数据不会改变
			this.arr[0].name = "gege";
			this.arr[0].age = 30;   //这种方式是可以检测到的, 这是更改的数组内部的对象的属性是可以检测到变化的
			//也可以使用 vue 提供的方法
			this.$set(this.arr,0,{
          
   id:1,name:"gege",age:30}) ; //这种方法也是可以的
			//还可以使用 vue 的变种函数
			this.arr.splice(0,1,{
          
   id:1,name:"gege",age:30});
			//这里的 splice方法其实已经不是 js 的 splice方法了, 它是被vue 改写过的方法
		}
	}

从上面我们可以看到, 如果想要通过数组下标修改数组的话, vue 是检测不到数据的变化的, 要么使用 $set , splice 等数组的方法, 要么就再向组数内部走一级, 直接修改内部对象的属性也是可以的

第二类, 对于对象

vue 是可以检测到对象中数据发生的改动的, 因为初始化的时候 对象的每一个属性 都生成好了 getter 和setter方法, 但是我们如果在程序运行过程中 动态的给对象添加新的属性, 删除属性, vue 是检测不到的

new Vue({
          
   
		data(){
          
   
			return {
          
   
				a:{
          
   
					b:"c"
				}
			}
		}

		......
		mehtods:{
          
   
			changes(){
          
   
				this.a.bb = "bbbb"; //这种写法是在 a 对象上面添加了一个 bb 的属性, vue 是检测不到的
				//所以这种情况下, 我们要使用 $set 
				this.$set(this.a,"bb","bbbbb");  //这样就可以解决问题, 
			}
		}

	})

上面只写了添加对象属性时的情况, 删除对象的属性时, 也可使用 $set


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

Object.assign(vm.userProfile, { age: 27, favoriteColor: ‘Vue Green’ })

你应该这样做:

vm.userProfile = Object.assign({}, vm.userProfile, { age: 27, favoriteColor: ‘Vue Green’ })

经验分享 程序员 微信小程序 职场和发展