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

相关推荐
清灵xmf20 分钟前
揭开 Vue 3 中大量使用 ref 的隐藏危机
前端·javascript·vue.js·ref
学习路上的小刘33 分钟前
vue h5 蓝牙连接 webBluetooth API
前端·javascript·vue.js
&白帝&33 分钟前
vue3常用的组件间通信
前端·javascript·vue.js
冯宝宝^2 小时前
基于mongodb+flask(Python)+vue的实验室器材管理系统
vue.js·python·flask
cc蒲公英2 小时前
Vue2+vue-office/excel 实现在线加载Excel文件预览
前端·vue.js·excel
森叶3 小时前
Electron-vue asar 局部打包优化处理方案——绕开每次npm run build 超级慢的打包问题
vue.js·electron·npm
小小竹子3 小时前
前端vue-实现富文本组件
前端·vue.js·富文本
青稞儿3 小时前
面试题高频之token无感刷新(vue3+node.js)
vue.js·node.js
程序员凡尘4 小时前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
Bug缔造者10 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js