没想到,以前为了面试背的虚拟dom,diff算法那些内容,竟然工作了这么久才在项目代码中接触到对应的场景(或者说意识到),事情是这样的.......
有这么一段代码:
<apply-file-ext ref="collegeJhApplyFile" v-if="activeDto === 'collegeJhApplyFileExtDtoList'" :config="config" :file-list="applyData.collegeJhApplyFileExtDtoList" dto="collegeJhApplyFileExtDtoList" :default-file-list="config.collegeJhApplyFileExtDefaultList" :columns="config.collegeJhApplyFileExtDtoList" :apply-data="applyData" :readonly="!isModify&&!importTab " />
这里其实是el-menu菜单下的组件展示,通过不同的activeDto来展示不同的组件。
而这里的v-if="activeDto === 'collegeJhApplyFileExtDtoList'"会导致一个问题,就是当你当前选中的activeDto不是'collegeJhApplyFileExtDtoList'这个页签时,取不到它对应的ref,此时如果你通过ref想去做校验的话,就会报错了。
这里的话倒是不难理解,因为v-if指令在false时是不渲染的嘛,也就是说当前dom并没有这个node,那么自然也就取不到它的ref了,于是我心想,这还不简单嘛,把它换成了v-show。
好嘛,以为简简单单的一个问题,换成v-show之后再测试,这下完了,这个页签组件的数据没了,这又是为什么呢?
再想一下,v-show跟v-if有什么不同,哦对了,show渲染一次后不再渲染,那也就是说,组件里面对应的生命周期函数只会执行一次,而我这里的数据是通过在mounted函数里赋默认值的,这不巧了吗。
那既然知道了问题所在,该怎么解决呢,我又想使用v-show来保证校验没有问题同时节省渲染负担,又想让我的数据能够在每次tab切换时重新更新,这样才能保不齐一些奇怪的需求或者操作会更新数据时这里能跟上不会出错。这时我想到了虚拟dom的key,只要让key值发生变化,这样即使是v-show也能被重新渲染了,也就是说我的数据也能正常拿到了,而由于这里每次切换tab,activeDto都会改变,那我只需要动态绑定一下并且再拼上一个组件专属的前缀就可以了,于是代码最终如下:
<apply-file-ext ref="collegeJhApplyFile" :key="'collegeJhApplyFile-'+activeDto" v-show="activeDto === 'collegeJhApplyFileExtDtoList'" :config="config" :file-list="applyData.collegeJhApplyFileExtDtoList" dto="collegeJhApplyFileExtDtoList" :default-file-list="config.collegeJhApplyFileExtDefaultList" :columns="config.collegeJhApplyFileExtDtoList" :apply-data="applyData" :readonly="!isModify&&!importTab " />