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

相关推荐
racerun8 分钟前
vue VueResource & axios
前端·javascript·vue.js
Calm55029 分钟前
Vue3:uv-upload图片上传
前端·vue.js
新中地GIS开发老师41 分钟前
《Vue进阶教程》(12)ref的实现详细教程
前端·javascript·vue.js·arcgis·前端框架·地理信息科学·地信
漫天转悠42 分钟前
Vue3中404页面捕获(图文详情)
vue.js
Cachel wood1 小时前
Django REST framework (DRF)中的api_view和APIView权限控制
javascript·vue.js·后端·python·ui·django·前端框架
天天进步20153 小时前
Vue项目重构实践:如何构建可维护的企业级应用
前端·vue.js·重构
2402_857583493 小时前
“协同过滤技术实战”:网上书城系统的设计与实现
java·开发语言·vue.js·科技·mfc
小华同学ai3 小时前
vue-office:Star 4.2k,款支持多种Office文件预览的Vue组件库,一站式Office文件预览方案,真心不错
前端·javascript·vue.js·开源·github·office
k09333 小时前
vue中proxy代理配置(测试一)
前端·javascript·vue.js
@解忧杂货铺9 小时前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js