左小白的技术日常
Github
2020/08/10
Author: guoqzuo

vue动态组件怎么动态绑定一个或多个v-bind属性

最近有封装一个tabs标签页组件,引入组件,可以将页面进行tab化。

原先的页面作为子组件放到tabs组件里,由于标签页跳转页面时有需要打开新的标签页。所以tabs组件里会包含多个页面组件。

为了避免像el-tabs那样,每次引入tabs组件都需要自己写v-if的逻辑来切换tab显示。我把这一步封装到了自定义tabs组件内部,内部使用动态组件component、is来切换组件显示。

为了页面tab化时最好不要改动,我需要根据不同的组件,动态v-bind不同的组件名。但问题是动态v-bind属性局限性很强,由于动态属性还包含修饰符,所以只能是单个的变量,不能是 tabs[curTabIndex].prop 这种写法,且这种方法只能传入一个参数,如果tab页组件需要传入多个参数,那怎么办?我暂时直接用options传入一个对象,在需要tab化的组件里转换一下才行。

如果需要更好的处理,可能需要写render函数了。

<component is="comsMap[tabs[curTabIndex]]" :[tabs[curTabIndex].prop]="tabs[curTabIndex].value"></component>

另外如果在动态组件里加了 keep-alive 也是有坑的,因为假如可以打开多个详情标签页,那多个标签页是同一个组件,只是不同的值在切换,如果加了keep-alive那每次打开的都是同一个详情页,我们可以使用watch监听下options值的变动,值改动时,触发页面数据跟着改变,也就是tabs页对于需要打开多个相同组件,不同内容的tab,是做不到keep-alive的,除非自己写缓存逻辑,-_-

组件封装的目的很简单,就是封装变化、减少代码量。易用性、可扩展、可维护性之间要寻找一个平衡。看哪些是必须要提供的功能,在这个前提下尽量精简,精简到不能继续封装为止。另外我们在使用这个组件时,需要做的工作尽可能少,代码尽量优雅。核心问题还是提高效率,增加代码结构化。

在大话设计模式的书里,有讲到,产品可能会频繁的变动、新增功能。我们要考虑到页面可能发生的各种变化,尽量在发生变动时,不用怎么改代码,这也是设计模式的核心理念:封装变化。这样才能写出更健壮的代码。