问题场景:当页面处于某个状态下时(业务场景是表单查看,不能操作),获取详情后二次设置选中tab,另一个tab则禁用,van-tabs
多个tab项动态设置了disabled
,v-model
绑定的值发生变化后,文字状态发生了改变但是下划线却没变化,且下划线的位置始终初始值所对应的tab,如下图所示:
查看元素会发现,左侧并没有具备.van-tab-active
样式,反而是右侧被禁用的tab同时具备.van-tab-active .van-tab-disabled
,disabled
设置成功了,但是选项的active
却没有跟着v-model
变化而变化。
我们打开vue-devtool找到van-tabs
,在内外层修改参数,我们发现。v-model绑定的值只修改了props里的active
,data里的currentIndex
以及computed里的currentName
都没有发生变化,我们尝试修改currentIndex
,发现下划线跟着变化了。同样的操作我们到官网操作一遍,active currentIndex currentName
是同步变化的。在生产环境打开devtools的方式生产环境打开devtools
因此,怀疑,组件在监听active
变化后改变currentIndex
的时候出了问题,我们打开源码,找到修改currentIndex
的代码,主要是setCurrentIndexByName setCurrentIndex findAvailableTab
三个方法。
我们打断点看一下,注意不是在这里打断点,走到浏览器的开发栏的source的js/chunk…js文件里,搜索van-tabs/index.js,找到以后打断点,页面刷新,debug那行代码时可以点击下钻,就会进入这个文件,搜索上述三个函数,合适的地方打上断点。
一通操作以后,我们发现二次赋值触发的findAvailableTab
返回的是个undefined,再走一遍,可以看到,我们即将把active对应的index赋给他时,发现被赋予的元素还是disabled状态,index被迫+1指向了不存在的地方,赋值失败。
此时,我们终于弄清楚了原因,动态绑定disabled和v-model值同时修改的话,active比disabled的转化更快,本应该转化为active状态的选项因为还处在disabled状态,转化失败。因此想要转化成功的话,我们要保证,转化为active状态的选项,我们要保证在转化的时候处于非禁用状态,此处,我采用的方法是,用两个字段disabled1 disabled2
控制选项的禁用状态,默认都是非禁用,二次赋值完以后,再在nextTick
里修改对应的disabled
this.tabs='b';
this.$nextTick(()=>{
this.disabled1=this.tabs==='b';
this.disabled2=this.tabs==='a';
})