响应式数据: 把data中的数据挂到vm身上,vm身上的这个数据其实就是响应式的一旦数据发生了改变,页面中的内容也会跟着改变
- 在日常开发中,为什么修改了data的数据,但是视图没有更新?
- 总结这个问题就是:当vue的data里面声明或者已经赋值过的对象或者数组(数组里面的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的
- 根据官方文档:定义如果在实例创建之后添加新的属性到实例上,它不会触发视图更新
- 原因:当你把一个普通的JavaScript对象传入Vue实例作为data选项,Vue将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter
- 受现代JavaScript的限制(以及废弃Object.obsserve),Vue不能检测到对象属性的添加或删除,由于Vue会在初始化实例时对属性执行getter/setter转化过程,所以属性必须在data对象上存在才能让Vue转换它,这样才能让它是响应的。
- 解决方案
- 可以使用$set()方法,既可以新增属性,又可以触发视图更新
- this.$set(要操作的数据,新增的内容,值)
//举例
<h2>{{obj.name}}----{{obj.age}}</h2>
<button click="add()">点我添加age<button/>
methods:{
add(){
//this.obj.age=19
this.$set(this.obj,"age",20)
console.log(this.obj.age)
}
},
data(){
return{
obj:{
name:"sally"
}
}
}
- 除此之外,在vue中数据发生了改变,DOM中的数据也会跟着发生改变,但是这个过程是异步的
vue的数据发生改变之后,DOM不会立即更新,会等到下一次渲染工作执行的时候才会更新DOM
- 解决方案
- 可以使用nextTick函数,确保在这个函数中可以到DOM结构是最新的
- this.$nextTick(()=>{})
clickFn () {
// 数据变化了, view中的内容也要跟着变
this.msg = '我是1'
this.msg = '我是2'
this.msg = '我是3'
this.msg = '我是4'
this.msg = '我是5'
this.$nextTick(()=>{
let result = document.querySelector('p').innerHTML
console.log(result) // 我是5
})
}