背景介绍透传是通信层面的一个概念,意思是在通信中,不管传输的是什么业务内容,它只负责将传输的内容从sourceaddress不对业务数据内容做任何改动,传输到目的地址。其实最早是从上面的一个领导那里听说透传这个概念的。由于他是一名电气工程师,透明传输在硬件通信中仍然被大量使用。对于透传,感觉有点眼熟。仔细想了想,发现其实我们的前端一直在使用透传,尤其是在做基础封装的时候。透传前端应用以一个Vue基础组件封装过程为例简单说一下什么是透传。相信很多前端er项目都会用到组件库,不管是ElementUI还是AntDesign,都无所谓。然后我们希望基于第三方组件库做一点定制。比如el-button有一个属性size,用来控制按钮组件的大小。属性描述类型可选值默认值sizeSizeStringmedium/small/mini-如您所见,默认大小相对较大。但是,当我们设计师基于组件库得出自己的设计方案时,我们选择的默认按钮尺寸可能正好对应ElButton的中等尺寸,或者其他值。这样,如果我不封装el-button,每个使用el-button的地方都要写一个额外的属性size,类似这样://pageA.vueButton1按钮2//pageB.vue按钮3Button4很明显每次用el-button都要写一个size属性,好烦啊!是的,确实很烦人,那怎么解决呢?答案是提供一个编程接口来更改组件的默认值。有这种考虑的组件设计者一般会提供设置默认值的接口,比如xxx.setDefault(options)。那么ElementUI和AntDesign有没有提供这样的能力呢?据我观察,好像没有,其实主要是vue没有方便的修改prop默认属性的方法。但是没有方便的方式不代表没有办法……由于本文的主题是透传,所以就不说那种方式(或方法)了,有点跑题了。网友小王说:“好吧,硬着头皮封装一个组件吧!”好的,马上安排!基本思路是封装一个自定义组件,在组件中调用el-button,强制el-button默认属性size="medium"。聪明的读者一看就会发现这个组件有大问题。除了size属性,其他属性和事件怎么处理完全没问题。小王说:“没关系,你需要什么?我来安排!”于是,这个组件最后慢慢变成了:看起来有点不好,这个组件会更冗余更复杂,因为我只在这里添加了3个道具和1个事件。稍微复杂一点的组件,总共有几十个道具和事件,随随便便!你身材匀称吗?而且很多人还有代码洁癖,简直让人受不了!冷静下来!当然有办法解决这个问题。强如框架的设计师游小友自然想到了这种场景,所以要注意Vue官网文档中的inheritAttrs[1]。如何理解选项inheritAttrs(默认值为true)?我们知道,如果一个组件想要接受来自父组件的属性,需要在props中预先定义。比如前面的例子,我在MyButton中预定义了3个属性,分别是size、type、disabled,也就是说MyButton只接受3个props。那么如果父组件传递4个或更多props会怎样呢?看下面的例子:component,so体现在HTML上是这样一个效果:作为用户,我们应该希望round和native-type="submit"可以传递给el-button,产生想要的效果。然而round和native-type="submit"只是挂在了根元素的属性上,并没有真正发挥应有的作用!PS:比如给el-button应用round属性可以让按钮有一个is-round类,从而产生圆角效果!也就是说,inheritAttrs的作用就是让那些没有定义在props中的属性直接以attribute的形式作用在组件的根元素上!那么round和native-type="submit"是怎么传递的呢?首先不能让那些没有被props标识的属性直接落在根元素上,所以需要设置inheritAttrs为false。然后,获取那些没有被props识别的属性,直接绑定到el-button上。恰好Vue提供了$attrs[2]来获取这些属性,而v-bind本身可以绑定一个对象,这一点很容易被我们忽略!处理完属性透传之后,我们接下来需要处理事件。和$attrs类似,$listeners也可以获取父组件到子组件的所有事件监听,这样我们就可以使用一个v-on来获取这些从父组件的事件监听传递给下一级组件.看图可能更好理解!相当于MyButton是一个中间人,不做差价,直接传消息!直观上,组件代码量明显减少,更重要的是扩展性和可维护性变强了!对于调用者来说,完全不影响用户体验,感觉还是直接在用el-button,属性传递和事件监听那里用户体验没有任何变化!总结结合inheritAttrs、v-bind、v-on,我们实现了一个支持透传的基础组件!本文以Button组件为例介绍透传的介绍。其实透传的适用范围远远超出了Button组件。有了透传技术,我们可以做更多美好的事情!现在,您的代码清洁度如何?