likes
comments
collection

第134期:用vue3结合hooks开发一个可以注册的二次确认弹框

作者站长头像
站长
· 阅读数 23

封面图

第134期:用vue3结合hooks开发一个可以注册的二次确认弹框

中午在公司楼顶平台上晒太阳,不知不觉睡着了

背景

上次开发了一个类似popConfirm的二次确认弹框,如下面两个图:

  • 图一

第134期:用vue3结合hooks开发一个可以注册的二次确认弹框

  • 图二

第134期:用vue3结合hooks开发一个可以注册的二次确认弹框

完成开发后,准备集成到项目中时忽然发现无法集成到公司内部的组件库中,因为公司的组件库表格的操作项按钮是通过传参的方式进行配置,无法直接使用popConfirm包裹操作按钮的方式进行Dom的书写。

所以又对二次弹框进行了一次简单的开发,采用modal的方式进行开发。好处是除了可以以之前的方式,直接在组件上传入props使用,如:

 <HConfirmModal  
     title="测试标题" 
     modalType="TextConfirm" 
     paperWork="hello-word" 
     :width="300" 
     v-model:visible="visible">
 </HConfirmModal>

也可以采用注册的方式,注册组件后,调用组件的api进行使用,如:

 <HConfirmModal  @register="register" @ok="testOK" ></HConfirmModal>
 
 const [register, { openConfirmModal: openModifyModal,setConfirmModalProps}] = useConfirmModal()

  function handleShow() {
    setConfirmModalProps({
      title:'测试标题',
      modalType:'TimeConfirm',
      desc:'注意危险'
    })
    openModifyModal(true)
  }

这样就可以比较方便的集成到现有的组件库中,也不需要改动现有组件库中的table相关的代码,相对来说效果也稍微好一些。

开发前想法

最早的实操方案打算借助于antd中的modal组件,对modal组件重新进行封装,但是发现:当我在modal组件中写入相应的dom结构后,如图:

  • 图一

第134期:用vue3结合hooks开发一个可以注册的二次确认弹框

  • 图二

第134期:用vue3结合hooks开发一个可以注册的二次确认弹框

modal组件中写入表单相关的dom后,需要我点击确认按钮时,对表单进行校验,这时候就需要能够直接获取Modal组件中的click事件。

那么,如何获取这个事件呢?

最开始的时候,也没想到很好的方法,后来想是否可以用ref来获取Modal的实例,然后调用这个实例上注册的事件呢?

也许可以,但是这样操作起来似乎有点舍近求远,毕竟除了表单校验的逻辑还有一个倒计时的罗需要进行判断,写起来似乎有些麻烦。

所以最终还是觉得借鉴Modal的样式,重新开发一个比较好,写起来比较舒服,效率也会高一点。

两种调用方式的实现思路

第一,使用props进行控制。这种组件实现起来比较简单,定义好组件需要的属性作为props,传递给组件,组件按照不同的属性进行渲染,点击时触发不同的emit事件即可。

其流程为:props和emit事件 ---> 渲染组件 ---> 触发emit事件

这种方式实现起来比较简单,但是场景稍微有些局限,如:组件的行为,如显示、隐藏必须在外部定义,需要外部书写相应的函数进行控制。

第二种方式,定义组件内部的方法,组件的行为通过组件本身的方法进行控制,同时将组件自身的方式通过hooks的方式暴露给外部。

其流程为:props和emit事件 ---> 组件定义自身需要的函数,同时将传入的props属性转化为内部属性---> 组件的行为根据自身的属性和方法进行控制---> 将组件本身的方法以hooks的形式暴露出来

这样一来,组件即可以以传统props的方式使用,也可以通过hooks的注册方法及组件本身的其他方法进行控制,使用的场景相对来说更广泛一些。

核心方法

传统的组件开发方式这里就不做过多的解释了,主要讲一下第二种方式的实现方式。

使用第二种方式开发组件的关键点有两处:

第一, 如何将外部传入的props转化为组件内部的属性 ?

第二,如何才能够获取到组件自身所定义的方法 ?

将外部传入的props转为组件内部属性其实很简单,我们只需要使用computed方式将转化一下即可,如:

  const getMergeProps = computed((): Recordable => {
      return {
        ...props,
        ...(unref(propsRef) as any)
      }
    })

这样我们就可以使用组件内部的属性getMergeProps对组件的dom进行渲染,实现不同的属性展示不同的内容。

那么,如何才能获取组件内部的方法呢?其实也很简单,这里需要用到一个vue提供的一个方法:getCurrentInstance

getCurrentInstance可以获取到当前组件的实例,既然可以获取到当前的实例,那么比必然可以操作实例上的方法。

然后,我们在组件实例化的时候触发一个注册函数register,将组件内部需要对外暴露的方法传给register方法,然后在对应的hooks中可以扩展实例的方法,这样我们就可以实现使用hooks的方式,注册、然后控制组件的各种行为。

这个触发的代码也很简单:

 const instance = getCurrentInstance()
    if (instance) {
      emit('register', modalMethods, instance.uid)
    }

最后,我们在hooks函数中可以获取组件的实例,拿到组件实例对象后,我们就可以为所欲为了。

最后

文章贴的代码较少,主要是觉得技术上还是需要以理解实现思路为主,有了思路我们就可以写各式各样的代码去实现功能,单纯的贴代码似乎没什么太大的意义。

作文写的不好,各位多多批评指教~

谢谢啦~