背景
前几天开发了一个二次确认的组件,这个事情基本上已经可以做个了结了。然后这周我们组内又该进行code review了,分享一下这个组件的代码就顺其自然的安排到了日程上。
因为疫情的缘故,上周整个一周都被限制了去公司办公,周一的时候解除了封控,去了公司,但是还是因为疫情的缘故,组内每天都只会安排一名同学到公司去,所以其他同学还是居家的状态,code review就以在线会议的形式展开了。
经过
我们的会议时长控制在一个小时,本来打算按照:组件的使用场景
--->个人开发前的想法
--->组件接收的props
--->代码的实现逻辑
--->核心的hooks
,这个流程去细致的过一遍组件的代码,当然,实际上也是按照这个流程去讲解的代码。
但是在讲解的过程中发现一些问题,在一些代码的细节问题上,虽然我用了这个 API,但是我对这个使用这个API可能出现的后果并不确定。比如:leader提出了关于watch
一个问题。
// 立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。 todo:
watchEffect(() => {
visibleRef.value = !!props.visible
})
watch(
() => unref(visibleRef),
(v) => {
emit('update:visible', v)
},
{
immediate: false
}
)
这两个方法看起来是实现的同一个功能,为什么还要写两次呢?
我也忘了我当时是怎么回答的,现在看来其实还是有必要写两次的。
因为watchEffect
监听的是props.visible
,props.visible
更新后,将更新后的值赋值给visibleRef
。
而watch
监听的是visibleRef
,visibleRef
更新后,去触发update:visible
这个事件,从而实现组件的v-model
功能。
一个监听组件外部的属性,一个监听组件的内部属性。
其次就是在处理组件上绑定的事件时,最好能够用try-catch
进行一个错误的捕获处理,以避免一些不可控的错误,虽然在之前的code review中讨论过这个问题,但是在开发中,我还是没有做这个处理。
// 取消事件 todo: try- catch
async function handleCancel(e: Event) {
// 如果是文本输入类型则 点击取消前 重置表单
getMergeProps.value.modalType === ModalTypeEnum.TextConfirm && formRef.value.resetFields()
// 如果是倒计时 则重置计时点
if (disabled.value && countDownNum.value) {
clearInterval(countDownTimer.value)
disabled.value = false
countDownNum.value = props.duration
}
e?.stopPropagation()
visibleRef.value = false
if (getMergeProps.value.onCancel && isFunction(getMergeProps.value.onCancel)) {
getMergeProps.value.onCancel()
} else {
emit('cancel', e)
}
}
第三,在定义组件接受的props时,对于事件的处理最好还是定义为emit
触发的形式,尽量别用props属性传递事件。公司内部的组件通常情况下emit
触发的形式已经可以满足项目的需求了,props属性传递事件通常在开源的组件库中使用的场景比较多,主要场景是用来以方法的形式调用组件时,作为回调函数使用。
if (getMergeProps.value.onCancel && isFunction(getMergeProps.value.onCancel)) {
getMergeProps.value.onCancel()
} else {
emit('cancel', e)
}
这里的getMergeProps.value.onCancel
和emit('cancel', e)
,一个是ConfirmModal.confirm()
调用时的回调,一个是正常组件绑定的事件,简单做了个兼容的处理。
其实在自己公司内部封装的组件,没有必要搞这么复杂。
其他的逻辑都是些非常简单的表单验证,定时器的使用...
本来想着讲一下组件内的基本代码,然后简单分享一下hooks函数的写法,可能是分享的时候语速有些慢了,加上偶尔需要回忆一下当时的想法,回答一些leader提的问题,结果组件的基本逻辑讲完已经差不多到会议结束的时间了。
结果
从整体的分享过程来看,这个过程基本上还算比较流畅,有些代码的细节自己能够很好的讲解出来,一方面是写的过程中没有考虑好具体的实现方法,另一方面是自己对api的细节及使用场景没有很好的掌握,还有一些是自己还是有些眼高手低的毛病,总觉得一个东西自己看过了、了解了就行了,但是真正的让自己讲的时候,其实自己也不知到该从哪里讲起。
总体来说,分享自己的代码并不是一件坏事,如果我们事后做些总结的话,会发现一些对我们个人非常有益的问题。
不论从编码层面,还是从认知层面,都能够收获一些东西。