实习半年后再看经典面试题:如何封装一个组件

前端同学们如果面试多的话可能会被问过这个问题:封装过组件不?你是怎么封装的?或者:如何封装一个组件?

忘记哪一次面试了,我也被问到过这个问题,当时答的并不好,粗略讲了一下我理解的流程。下来又问了一下豆包,给出的答案是这样的

面试官真的就只是想听一下这种无聊的最基础的流程吗?我觉得不是。最近做的需求刚好封装了一个通用组件,那天走在路上想要写什么话题,突然想到这个,那就看下实习到现在的我,回头看这个问题又有哪些理解,大家可以看下我的思路,并结合自己的一些理解,尽可能完美的给面试官解答这个问题(下文若涉及到技术栈皆以React为例,Vue同理类比即可)。

首先,在进行组件封装之前,我们要明确一个点:我们要封装的是否是一个通用组件。

为什么要明确这个点?因为是否是一个通用组件会涉及到很多内部逻辑的书写,包括接口和hook的定义和使用。如果你是封装一个只有自己使用的组件,那么你的数据获取可以直接在组件内部调用接口,这样就可能不需要在props中预留传数据参数的属性。如果你封装一个通用组件,除了数据应当通过props传入以外,你还需要考虑组件放在什么位置,需要预留哪些props属性,让后续使用者尽可能的好复用。好的组件一定是要有足够强的可维护性和足够方便的可使用性的。

上面的这段话没有实习过的同学可能觉得有点抽象,我给大家举个case:

假设你有一个系统,系统中有一个审批模块,审批模块中可以用到的审批按钮在整个模块中的逻辑包括交互都应当是一样的,这样的一套按钮应当被封装为一个通用组件,方便各审批页面进行使用。这样的话,你在封装这个组件时就应当预留至少以下几个属性:1.需要审批的内容信息;2.审批后调用的方法或者函数(比如刷新table,刷新页面,跳转页面等),除此之外根据业务场景可能还需要加一些定制化的属性比如用户信息以方便获取权限等等。所有需要通过请求得到的审批内容信息应当从接口获取并通过props传入组件,而如果是非通用接口则可以在组件内部调用接口获取。

明确了这个组件是否是通用组件后,就要看这个组件会用在什么位置,如果只是你这个页面使用,那就放在当前页面组件同层级或组件文件夹下的component文件夹中,如果是通用组件,那么就应当定义在共用的定义组件的位置。以我们的项目为例,使用微前端架构,多个子应用想要共同使用同样的组件时就会从shared-component这样一个单独的文件夹中获取组件。并且我们由于考虑到发包的问题,使用shared-component中的组件使用的是产物引入,而自己页面使用的组件通常使用直接引入(这并不意味着通用组件就必须使用产物引入,具体的引入方式还是要看项目本身使用什么比较方便或者有没有什么发包诉求)

这里顺便提一下产物引入和直接引入的区别。

  • 直接引入顾名思义,就是直接引用你写的组件,比如import Component from './my/Component.tsx';而产物引入就是引用经过构建、编译或者打包等操作后生成的产物。例如在前端项目中,引用经过 Webpack 打包后的 JavaScript 文件。以我们shared-component为例,在这里定义的时候我们会将这些定义的组件都通过index文件导出,由于要导出很多的组件内容,所以意味着你的组件只能使用具名导出,不能使用默认导出
  • 直接引入的好处:直接引用具有较高的灵活性,你可以随时修改组件,并且hmr会立即生效。但产物引入的话,由于每次改动都需要打包才能生效,因此开发过程中调整的效率比较低。
  • 产物引入的好处:可以发包(npm/pnpm等)。发包意味着依赖的引用是稳定的,不会轻易产生依赖冲突。这在微前端项目中及其有用,试想项目中的子应用可能各应用使用的依赖版本都不一样甚至技术栈都不一样,那么直接引用的话可能就会出现依赖版本冲突,这个问题还是相对常见的,而使用产物引入一般不用考虑这个问题,只需要考虑你引用的产物版本是否正确即可。

回到问题本身,接着就是定义入参,定义入参的时候,通用组件需要跟其他模块的同学对好字段,预留好props字段。定义hooks、type和const时也应当单独定义并导出方便后续同学使用。再后面就跟豆包说的差不多了,写内部逻辑,写组件样式,导出并引用。

所以这段时间我对这个问题的思考主要是集中在定义组件是否是通用组件以及二者的区别上,在面试时提到这一差别可能会让面试官感到耳目一新,并且凸显自己的思考。也许就是这一个亮点,可以覆盖你前面的许多瑕疵。

#面试题刺客退退退##大家都开始春招面试了吗##软件开发笔面经##前端##牛客激励计划#
全部评论
同感
点赞 回复 分享
发布于 04-01 11:41 北京

相关推荐

用户增长 - 一面手撕:LRU- 平时的学习成绩怎么样?- 请介绍一下你的实际经历,重点说说你在货拉拉做了什么,遇到了哪些问题?- 这个项目是为了解决什么问题?- 为什么不使用 MongoDB?这种场景听起来用 MongoDB 更合适吗?- 为什么响应时间(RT)会很大?原因是什么?- 如果 Redis 不可用,你们会怎么处理?- AES 存储是下发给司机的吗?我理解是这样,对吗?- 司机的密钥和你们的是同一个吗?- AES 里面存储的是什么内容?- 如果我拿到了 AES 的 token,是不是就能模拟登录了?- 这个和时间戳有什么关系?- token 是如何进行对比的?时间戳怎么对比?- 时间戳的作用是什么?- 如果别人拿到了这个 token,能不能直接登录?- 本地缓存和 Redis 二级缓存的机制能详细讲一下吗?它解决了什么问题?- 缓存的是什么内容?是活动详情还是第一层缓存的数据?- 活动内容不会发生变更吗?- 本地缓存具体是怎么实现的?这对后端压力没有影响吗?- 你有做过性能对比吗?- 平时用 HTTPS 还是 HTTP 比较多?- 有没有用过 RPC?- HTTP 有哪些请求方法?- 你了解 PUT 方法吗?- 用 POST 接口也能实现删除操作,为什么还需要单独的 DELETE 方法?- 只用 DELETE 不安全吗?- 既然 POST 更安全,为什么还需要 DELETE 方法?- 你了解 HTTP 的状态码吗?用户增长-二面手撕:- 你觉得哪段经历对你的成长帮助最大?- 你在这段经历中主要负责什么?- 在这个项目中,有什么让你觉得惊艳的想法或新技术?你学到了什么?- 你刚才提到的是用 Redis 把订单 ID 和活动 ID 关联起来吗?还是用的其他方式?- 权益卡的相关内容是怎么生成的?- 你说的瓶颈是指下单时根据距离和车型获取活动 key 列表的压力吗?- 为什么说是订单 ID 和活动列表的问题?- 下单时还需要再获取活动列表吗?这个性能问题没办法避免吗?- 大对象不会影响引用数目,是不是?- 你还做了哪些方面进行预防这种情况?- 如何保证数据一致性?- 如果是分布式服务,多台服务器上本地缓存更新不一致怎么办?- 你是怎么把路由写入每个本地缓存的?- 什么时候通知 Redis 更新数据?是写入时同时通知吗?
点赞 评论 收藏
分享
评论
14
35
分享

创作者周榜

更多
牛客网
牛客企业服务