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

相关推荐
疯狂的沙粒15 分钟前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员31 分钟前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
想自律的露西西★1 小时前
用el-scrollbar实现滚动条,拖动滚动条可以滚动,但是通过鼠标滑轮却无效
前端·javascript·css·vue.js·elementui·前端框架·html5
白墨阳2 小时前
vue3:瀑布流
前端·javascript·vue.js
程序媛-徐师姐3 小时前
Java 基于SpringBoot+vue框架的老年医疗保健网站
java·vue.js·spring boot·老年医疗保健·老年 医疗保健
余道各努力,千里自同风4 小时前
前端 vue 如何区分开发环境
前端·javascript·vue.js
PandaCave4 小时前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
软件小伟4 小时前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾4 小时前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
chusheng18405 小时前
Java项目-基于SpringBoot+vue的租房网站设计与实现
java·vue.js·spring boot·租房·租房网站