Vue3基于antdv指令式封装自定义组件的全局弹窗Hooks方法

功能和作用介绍

通过指令式的hooks方法弹窗弹出自己写的任意组件,可以弹出一个全局表单,或者全局树(通讯录)这种弹窗,在确认时拿到所需的数据。

描述就不多描述了,我也只是个菜鸟,更多的是只会用,不太了解为什么。 直接放代码了,不足之处请指出,有些方法我觉得可以优化,但是没琢磨出来。

灵感及方法来源于:Vue3 组件封装进阶,简简单单实现一个弹窗表单组件 - 掘金 (juejin.cn)

效果演示

代码实现

hooks方法

js 复制代码
import {h} from 'vue'
import {Modal} from 'ant-design-vue'

const useModalHooks = options => {
  return new Promise((resolve, reject) => {
    const onOk = close => {
      const exposed = vNode.component.exposed
      exposed.onHandleSubmit(resolve, close)
    }

    const onCancel = () => {
      reject({errMsg: '取消', error: false})
    }
    options.modalApi = options.modalApi || {} // modal的api
    options.props = options.props || {} // 组件传递参数
    const vNode = h(options.content, {options: options.props})
    Modal.confirm({
      icon: null,
      content: vNode,
      closable: true,
      ...options.modalApi,
      onOk,
      onCancel
    })
  })
}
export default useModalHooks

组件中注意事项

组件中必须含有且暴露出这个方法,这个方法与hooks中onOk中定义的方法一致。 用h函数渲染的组件中第三方UI组件库内部需要重新引用

在确认操作中我们可以在这个方法中操作这个组件的方法与数据(比如校验、请求等等)

用 resolve 将想要传递的数据传递出去,close 决定是否关闭这个弹窗

vue 复制代码
<template>
  <a-form class="login-form" ref="formStateRef" :model="formState" name="basic" autocomplete="off">
    <a-form-item name="username" :rules="[{required: true, message: '请输入账号!'}]">
      <a-input v-model:value="formState.username" allowClear size="large" placeholder="请输入账号">
        <template #prefix><UserOutlined style="color: rgba(0, 0, 0, 0.25)" /></template>
      </a-input>
    </a-form-item>

    <a-form-item name="password" :rules="[{required: true, message: '请输入密码!'}]">
      <a-input-password
        type="password"
        v-model:value="formState.password"
        allowClear
        size="large"
        placeholder="请输入密码"
      >
        <template #prefix><LockOutlined style="color: rgba(0, 0, 0, 0.25)" /></template>
      </a-input-password>
    </a-form-item>
  </a-form>
</template>

<script setup>
import {ref, reactive, onMounted} from 'vue'
import {LockOutlined, UserOutlined} from '@ant-design/icons-vue'
import {Form as AForm, FormItem as AFormItem, Input as AInput, InputPassword as AInputPassword} from 'ant-design-vue'
const props = defineProps(['options'])
console.log(props.options)
const formState = reactive({
  username: '',
  password: '',
  repassword: '',
  remember: false
})
const onSubmit = () => {
  console.log('登录')
}
const formStateRef = ref()
const onHandleSubmit = (resolve, close) => {
  formStateRef.value
    .validate()
    .then(() => {
      resolve(JSON.parse(JSON.stringify(formState)))
      close()
    })
    .catch(error => {
      return false
    })
}
defineExpose({onHandleSubmit})
</script>

<style scoped lang="less"></style>

使用hooks方法

方法的使用无非就是引入传参

vue 复制代码
<template>
  <a-button class="page-btn" type="primary" @click="openTestAppModal">测试打开弹窗</a-button>
</template>

<script setup>
import useModalHooks from '@/hooks/useModalHooks'
import TestForm from '@/components/TestForm.vue'
const openTestAppModal = () => {
  useModalHooks({
    content: TestForm,
    modalApi: {
      title: '测试'
    },
    props: {
      a: 1,
      b: 2
    }
  })
    .then(data => {
      console.log(data)
    })
    .catch(err => {
      console.log(err)
    })
}
</script>

<style scoped lang="less"></style>

事实上我写完曾怀疑是不是多此一举了,因为antdv的modal这个方法本身就可以渲染组件,不过想来可能不能直接获取这个组件的数据吧,或许是我不太了解h函数的具体使用。

相关推荐
飞天大河豚9 分钟前
2025前端框架最新组件解析与实战技巧:Vue与React的革新之路
vue.js·react.js·前端框架
customer082 小时前
【开源免费】基于SpringBoot+Vue.JS医疗报销系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
道不尽世间的沧桑2 小时前
第9篇:插槽(Slots)的使用
前端·javascript·vue.js
B站计算机毕业设计超人2 小时前
计算机毕业设计SpringBoot+Vue.jst房屋租赁系统(源码+LW文档+PPT+讲解)
vue.js·spring boot·后端·eclipse·intellij-idea·mybatis·课程设计
bin91532 小时前
DeepSeek 助力 Vue 开发:打造丝滑的滑块(Slider)
前端·javascript·vue.js·前端框架·ecmascript·deepseek
杰九2 小时前
【环境配置】maven,mysql,node.js,vue的快速配置与上手
java·vue.js·spring boot·mysql·node.js·maven
秋意钟3 小时前
Element UI日期选择器默认显示1970年解决方案
前端·javascript·vue.js·elementui
程序员黄同学4 小时前
请谈谈 Vue 中的 key 属性的重要性,如何确保列表项的唯一标识?
前端·javascript·vue.js
繁依Fanyi4 小时前
巧妙实现右键菜单功能,提升用户操作体验
开发语言·前端·javascript·vue.js·uni-app·harmonyos
web182854825124 小时前
nginx 部署前端vue项目
前端·vue.js·nginx