资讯专栏INFORMATION COLUMN

解决<el-checkbox-group> 数据与UI更新不同步的坑

Nino / 3400人阅读

摘要:情景再现上午下午晚上周一周二周三周四周五周六周日周一的选择情况周二的选择情况周三的选择情况周四的选择情况为赋值得到这样的结果但是当我们点击其它选择框的时候,没有反应。个人认为与的数据同步有些问题。

Bug情景再现


得到这样的结果:


但是当我们点击其它选择框的时候,没有反应

尝试解决

最先想到的原因应该是vue没有对arrange的改变监控到, 于是解决办法是使用 vue. set

this.$set(this.storeItem,   "arrange",  week)

这样修改后确实也起作用了。
⭐ 注意:这里使用 vue.set 起作用根本是,瞎猫碰上死耗子,不能相响应的原因根本不是这个
而且我们仔细读 Vue 的官方文档
Vue.set( target, key, value )
作用是向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = "hi")

这里我们根本没有添加 arrange属性,而只是去改变了arrange 属性的值,vue按理说应该是能够检测到的。后面的实验也认证了我的观点。

实验:让我们再把表单复杂一些。
注:部分代码已经省略



这样写了之后, checkBox 还是: 能够展示勾选,但是点击其它选择框没有任何反应。

于是我们将 mounted 里面的代码改成

const week = [
            [1,2],        //周一的选择情况
            [1],          //周二的选择情况  
            [],           //周三的选择情况
            [2,3],         //周四的选择情况
            [2,1],
            [1,2,3],
            [3]
        ]
        //为checkbox-group 赋值

        const  _obj = {};
        const  self  =  this;
        
        for (let i=0; i<3; i++){
               _obj = {}; 
               _obj.name = `这是  ${i} 号`;
               _obj.arrange = week;
               self.$set(self.serviceStoreList,   i,    _obj)
               // 或
               self.serviceStoreList.splice(i,  1,  _obj)
        }

还是不会起任何作用,点击其它选择框依然是点不动,不能进行交互

这里我反复实验了几次,发现了一个特殊的现象。就是当你去点击其它选择框的时候, vue-devtool 里面显示的数据其实是已经改变了的。
而且,当你点击了一个checkBox, 然后去填写另外的一个表单项,比如去选择下拉,或者填写其它 的时候,
checkBox 立刻就改变了。相当于它之前的v-model 的数据其实是正常的,只是视图卡住了。

最后的解决办法

vue 的数据没有问题,那么肯定是 element 埋下的坑。
个人认为 的数据同步有些问题。
这样写就好了


         上午
         下午
         晚上


//data 里面增加一个字段
data (){
    checked:false ,           //这个 checked没有任何作用,只是为了绕开elment 的这个坑
}

这样我们不用设置 vue.set(因为vue 其实重头到尾都能够监视到数据的改变)

const week = [
        [1,2],        //周一的选择情况
        [1],          //周二的选择情况
        [],           //周三的选择情况
        [2,3],        //周四的选择情况
        [2,1],
        [1,2,3],
        [3]
    ]
//为checkbox-group 赋值
const  _obj = {};
const  _store = [];
for (let i=0; i<3; i++){
    _obj = {};
    _obj.name = `这是  ${i} 号`;
    _obj.arrange = week;
    _store.push(_obj);
}
this.checked = false;            //需将checked 设置为false,不然选择框可能会出现全部选中的情况
this.serviceStoreList = _store;  //直接设置,checkbox也能正常交互
心得

vue 只是 无法探测普通的新增属性 ,但是 Vue 能够探测到data 里面已经注册过的对象的改变,比如重新给这个对象赋值,或改变它已经注册过的属性的值(非给它新增其它属性)。无论这个对象的数据结构有多么的复杂。

少用 vue.set, 多在 上面显示指明 @change,让它状态改变。

再每次修改 的 v-model 的值的时候,先将 checked 设置为 false

1. this.checked = false
2. this.serviceStoreList =  _store

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102732.html

相关文章

  • 解析vue表单验证rules及validator验证器的使用方法

      很多知识都是需要提早知道,才可以规避很多错误。  Element中Form (表单)组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可。  注意:prop对应表单域 model 字段,使用 validate方法时,该属性是必填的。  表单验证rules  以官网给出的例子分析来看  将prop属性设置为...

    3403771864 评论0 收藏0
  • Spring事务&分布式事务&单服务处理多数据源事务

    本文以一个实际业务问题来谈谈事务该如何处理。对接外部系统是是不可避免的,从广泛意义上来说,外部系统范围很大,中间件(数据库)也属于外部系统。当我们讨论事务时,通常我们将那些没有支持事务的系统称为外部系统,业务系统基本上都是外部系统。问题有这样一套系统,以gitlab为底层系统, 在gitlab project的基础上封装了代码仓,系统对其中一些与gitlab关联的数据进行了落表。创建代码仓的逻辑过...

    社区管理员 评论0 收藏0
  • UCloud私有云双活数据中心解决方案,强效保障业务可靠性和连续性

    引言据信通院《2022云计算白皮书》报告,国内云计算市场达3000亿规模,云计算成为企业数字化转型的基础设施已是大势所趋。随着企业数字化转型的逐步深入,业务发展与IT基础架构演进密不可分,如何保障数据隐私安全和业务连续性,是 IT 建设中必须关注的问题。出于数据隐私和安全性考量,私有云解决方案成为构建数字化转型的基础底座,通过同城双活及两地三中心的高可用架构保障生产环境稳定性和业务过程连续性;同时...

    社区管理员 评论0 收藏0
  • MySQL日志-binlog/redo log/undo log什么区别

    一、前言MySQL 整体来看,其实就有两块:一块是Server层,它主要做的是MySQL功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(归档日志)。二、Redo logWAL技术的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘。当有一条记录需要更新...

    社区管理员 评论0 收藏0

发表评论

0条评论

Nino

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<