响应式数据($set、$nextTick)

907 阅读1分钟

响应式数据: 把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更新后执行,当vue更新完DOM后,会自动调用nextTick()方法,其会在DOM更新后执行,当vue更新完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
   })
}