使用vue双向绑定的时候,有时候会遇到没有检测到数据变化的情况,以下情况,是需要在平常工作和使用中注意的问题
数组盲区
vue包含一组观察数组变异的方法,使用这些方法也会触发视图更新
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
但是受到某些限制,vue无法检测到以下数组变动(视图不会更新)
<template>
<div>
<button @click="event">click</button>
{{items}}
</div>
</template>
<script>
export default {
data() {
return {
items: ['a', 'b', 'c']
}
},
methods: {
event() {
this.items[1] = 'x' // 不是响应式的
this.items.length = 2 // 不是响应式的
console.log(this.items)
}
}
}
</script>
为了解决这个问题,需要使用$set
<template>
<div>
<button @click="event">click</button>
{{items}}
</div>
</template>
<script>
export default {
data() {
return {
items: ['a', 'b', 'c']
}
},
methods: {
event() {
// this.items[1] = 'x'
// this.items.length = 2
this.$set(this.items, 1, 'x')
this.items.splice(2)
console.log(this.items)
}
}
}
</script>
对象盲区
vue不能检测对象属性的添加和删除
<template>
<div>
<button @click="event">click</button>
{{items}}
</div>
</template>
<script>
export default {
data() {
return {
items: {
a: 1 // 是响应式的
}
}
},
methods: {
event() {
this.items.b = 2 // 不是响应式的
console.log(this.items)
}
}
}
</script>
这里有两种解决方法
- 在data声明时,就给出b: ''的声明
<template>
<div>
<button @click="event">click</button>
{{items}}
</div>
</template>
<script>
export default {
data() {
return {
items: {
a: 1 // 是响应式的
}
}
},
methods: {
event() {
this.$set(this.items, 'b', 2) // 是响应式的
console.log(this.items)
}
}
}
</script>
当你想添加多个新属性到某个对象上时,也可以利用Object.assign(),但是不要直接给this.yourObject添加,例如
// 此时也不是响应的
Object.assign(vm.items, {
c: 3
})
可以直接赋值给原有对象
// 此时是响应式的
this.items = Object.assign({}, this.items, {
v: 3
})