数据改变但是视图不变的原因以及解决方法
我们都知道,vue的特点之一就是数据驱动视图,也就是当我们的数据发生改变的时候,视图也就随之改变了,不需要我们再进行更新视图的操作,但是有一些情况,我们虽然改变了数据,但是视图并没有变化,官网是这样解释的:由于 JavaScript 的限制,Vue 不能检测数组和对象的变化,其实我认为应该说vue不能检测未挂载的即后来添加的新属性,所以需要我们进行一些操作达到我们想让vue检测的目的对于对象Vue
·
我们都知道,vue的特点之一就是数据驱动视图,也就是当我们的数据发生改变的时候,视图也就随之改变了,不需要我们再进行更新视图的操作,但是有一些情况,我们虽然改变了数据,但是视图并没有变化,官网是这样解释的:由于 JavaScript 的限制,Vue 不能检测数组和对象的变化,其实我认为应该说vue不能检测未挂载的即后来添加的新属性,所以需要我们进行一些操作达到我们想让vue检测的目的
对于对象
- Vue.set()
通过代码展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{show}}
<button @click="add">添加b</button>
</div>
<script src="./vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data(){
return{
show:{
a:"我是a"
}
}
},
methods: {
add() {
this.show.b = "我是b"
console.log(this.show)
}
}
})
</script>
</body>
</html>
效果:
当我们点击按钮的时候,我们可以发现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
那我们怎么改变数组已经定义好的元素呢?
- 方法一:变更方法(这种都是修改原数组)
就拿我们通过索引来修改原数组
代码举例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{{arr}}
<button @click="btn">点击</button>
</div>
<script src="./vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
arr: [1, 2]
},
methods: {
btn() {
this.arr[2] = 3
console.log(this.arr)
}
}
})
</script>
</body>
</html>
效果:
跟改变对象属性很类似,那个是用到了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)
}
}
})
更多推荐
已为社区贡献7条内容
所有评论(0)