能获取到数据 数据却渲染不到页面上

问题描述: 数据改变了,数据打印出来都正确,但是页面里面就是不显示、没变化。

很多时候对数据进行处理了,但是页面上就是没变化,没效果,用 console.log 打印数据都没问题,特别是数组、对象容易出现这个问题;

解决方法

1、 this.$set( xxx )

Vue.set( target, propertyName/index, value )
//this.$set(item, 'pics', pics) 

保存变量,(向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性)

2、 this.$delete( xxx )

Vue.delete( target, propertyName/index ) 

删除对象的属性,(如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到属性被删除的限制,但是你应该很少会使用它)

3、this.$forceUpdate( xxx )

强制更新,迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。

问题原因

这个就需要了解 Vue 是如何实现数据的响应式, vue响应式实现分为两块:对象和数组

对象

Vue 让 对象 数据变得“可观测” 是通过重写 Object.defineProperty()方法中的 get 和 set 方法; 在getter中收集依赖,在setter中通知依赖更新,至于怎么创建的、怎么去通知 dom 更新有兴趣的同学可以去看看源码;

不足: 虽然 vue 递归了对象属性并添加了依赖,但是当我们向object数据里添加一对新的key/value或删除一对已有的key/value时,它是无法观测到的,导致当我们对object数据添加或删除值时,无法通知依赖,无法驱动视图进行响应式更新;为了解决这一问题,Vue增加了两个全局API:Vue.set和Vue.delete;

数组

Vue 让 数组 数据变得“可观测” 与对象类似,Vue 中创建了一个数组操作方法的拦截器 push,pop,shift,unshift,splice,sort,reverse 重写了这些操作数组的方法,当调用这些方法时也是在getter中收集依赖,在setter中通知依赖更新;

不足: 通过数组下标修改数组中的数据、通过修改数组长度清空数组,这种操作方式来修改数组是无法侦测到的,但是同样可以使用Vue.set和Vue.delete 来解决这个问题; Object.defineProperty 举例:

在这里插入图片描述

代码如下

let data = {}
let title= '动态变化的标题'
Object.defineProperty(data, 'title', {
  enumerable: true,
  configurable: true,
  get(){
    console.log('title属性被读取了')
    return title
  },
  set(newVal){
    console.log('title属性被修改了')
    // 去更新dom
    title= newVal
  }
}) 
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐