一、问题描述

是否有遇到过,数据更新后,界面并没更新的现象?排除数据请求时的先后问题,这是怎么回事呢?

基本的问题就是当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。

二、问题分析

如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。

受 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。

由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

三、解决方式

Vue不允许在已经创建的实例上动态添加新的根级响应式属性。向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性,这里就提供了一个关于Vue.set的使用,从而来解决这一类问题。

Vue.set( target, propertyName/index, value )
参数:
    target: 是一个Object对象 或 是Array数组
    propertyName/index: 对象的话就是key,数组即是下标index
    value: 需要设置的值

四、项目场景中

  • 项目图片参考
    Snip20190523_98.png
  • 商品选中状态实现
    页面中有多少个商品,其对应选中与否的状态在 selectList: []中存放着。例如图中所看到的那么数组中的数据对应的是[false, false, false]
  • 实现效果
    其中在每个商品中有复选框,当底部全选选中时,需要同步更新到所有商品;同样取消选中也需要同步到所有商品的选中状态。
  • 代码参考

    // 全选点击的方法处理
    onCheckAll: function(){
                for(var i=0; i<this.selectList.length; i++){    // 遍历selectList数组
                    // 以下方法,数组虽然是更新的,但界面是不会跟随跟新的                        
                    // this.selectList[i] = this.isAll
    
                    // 这就需要使用到 Vue.set 方法来处理这个数组
                    this.$set(this.selectList, i, this.isAll)
                }
            }

本文由 zyz 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

楼主残忍的关闭了评论