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函数的具体使用。

相关推荐
paopaokaka_luck12 小时前
基于SpringBoot+Vue的社区诊所管理系统(AI问答、webSocket实时聊天、Echarts图形化分析)
vue.js·人工智能·spring boot·后端·websocket
余道各努力,千里自同风12 小时前
el-input 输入框宽度自适应宽度
javascript·vue.js·elementui
Southern Wind13 小时前
Vue 3 多实例 + 缓存复用:理念及实践
前端·javascript·vue.js·缓存·html
一大树13 小时前
Vue3优化指南:少写代码,多提性能
vue.js
90后的晨仔13 小时前
Webpack完全指南:从零到一彻底掌握前端构建工具
前端·vue.js
90后的晨仔14 小时前
Vue3项目全面部署指南:从构建到上线
前端·vue.js
重生之我要当java大帝14 小时前
java微服务-尚医通-数据字典-5
vue.js·微服务·云原生·架构
Shi_haoliu14 小时前
Vue2 + Office Add-in关于用vue项目于加载项控制excel单元格内容(Demo版)
前端·javascript·vue.js·node.js·html·excel·office
计算机毕业设计木哥15 小时前
计算机毕业设计选题推荐:基于SpringBoot和Vue的爱心公益网站
java·开发语言·vue.js·spring boot·后端·课程设计
知识分享小能手21 小时前
uni-app 入门学习教程,从入门到精通,uni-app基础扩展 —— 详细知识点与案例(3)
vue.js·学习·ui·微信小程序·小程序·uni-app·编程