「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战」。
最近想要迁移Vue2的项目到Vue3,迁移过程中发现原有代码里使用了很多 slot指令例如slot = 'xxx' 跟 slot-scope = ’xxx' 直接在组件上的旧写法,每迁移一个页面就有很多类似的代码要重构不改的话会报错,原因是在2.6.0版本slot跟slot-scope写法已经过时,新出v-slot指令替代,与v-bind v-on 等类似可用语法糖#,slot跟slot-scope的旧写法上到Vue3 则彻底不可用。
因为项目版本 为 2.6.+, 可以使用v-slot指令,而且搜了一下项目有上千个slot跟slot-scope。 所以决定抽空全局重构,为后续迁移节省一点成本。下面介绍一下v-slot指令以及重构思路步骤。
v-slot
熟悉模板引擎语言例如Jinja的同学都知道,slot是插槽的意思、在模板中预留一块区域,可以被具体实现模板的页面重新实现、替换。
在Vue中插槽可作为子组件的预留区域,父组件中实现的插槽可以访问当子组件预留区域的变量,slot跟slot-scope写法不赘述,感兴趣可以翻阅官方文档。
而对于v-slot 指令,有如下几条规则:
-
v-slot 不能用在HTML标签上,如 div span p等标签,只能用在template或者组件上,否则vue会报错;
-
当v-slot用在组件上的时候,组件内又有一个
<template v-slot>,这样的话Vue也会报错因为scope不明确,例如<component #slotProps> <template v-slot:child></template> </component> -
v-slot 跟 旧的 slot 跟 slot-scope语法一起用时,Vue还会报错因为旧的语法在Vue3中被废弃了;
-
<template v-slot>不能作为HTML 的子节点; -
多个v-slot的话,只有第一个有效,其余的被忽略。
重构
下面介绍一下重构的思路,本来想用jscodeshift,用脚本重构可能效率跟精准度都比较好,奈何学艺不精,对jscodeshift的掌握程度不够,所以决定用正则去替换将例如<div slot="xxx"></div> 的代码替换成为 <template #xxx><div></div></template>。
步骤拆解为:
-
识别到 对应的标签;
-
加上template v-slot标签;
-
去除掉原有的slot标签。
具体实施为:
-
打开vscode的全局搜索;
-
由于项目里基本都是几种组件具有slot属性所以对每个分批进行处理 :
<xxx.?slot="(.?)".?\/?>[\n]+([\s\S])?<\/xxx>=><temlate #$1>$0</template> -
<xxx (slot=".?")(.?)>=><xxx $2> -
对于每个比如div,span组件进行以上重复操作;
-
<template slot-scope>则类似第三步统一替换。
以上是用正则重构slot标签的思路跟具体步骤,结果则不方便截图了。用时大约两个小时,因为一边调试一边确保替换后的结果是可以运行的,vscode还有个坑,当一个文件有两个及以上含slot的tag时点全部替换(ctrl+shift+enter),第二个及以后都会被替换成第一个slot的值,可能是写入的结果不能及时同步导致的,所以对于两个及以上slot的文件需要单独处理,即一个一个点击替换(ctrl+shift+1)。总结是对于有规则的替换可以合理使用正则跟脚本,减少重复操作带来的枯燥感。如有更高效的重构方法,欢迎评论区留言。
感谢阅读
Happy coding