ant-design中的Modal组件有两种用法:
第一种是用标签:<a-modal></a-modal>
第二种是用Api:Modal.info、Modal.warning、Modal.confirm......
一开始项目中这两种用法是混用的,后面UI改造,需要统一样式,步骤如下:
1、封装全局弹窗组件 src/components/ConfirmModal/index.vue
<template><a-modalv-model:visible="visible":title="props.title"centeredwidth="400px":footer="null":keyboard="false":maskClosable="false"destroyOnClose@cancel="cancel"><div v-if="vNode" ref="contentRef" class="text-align-c mt-16"></div><div v-else class="text-align-c mt-16">{{ description }}</div><footer class="text-align-c mb-24 mt-40"><template v-if="footerVNode1 || footerVNode2"><a-button v-if="footerVNode1" ref="footerRef1" class="long-btn" @click="cancel"></a-button><a-buttonv-if="footerVNode2"ref="footerRef2"type="primary":class="[footerVNode1 ? 'ml-40' : 'ml-0', 'long-btn']"@click="cancel"></a-button></template><template v-else><a-button class="long-btn" @click="cancel">取消</a-button><a-button class="ml-40 long-btn" type="primary" :loading="btnLoading" @click="confirm">确认</a-button></template></footer></a-modal>
</template>
<script setup>
import { ref, render, nextTick } from 'vue'
import { Button, Modal } from 'ant-design-vue'const AButton = Button
const AModal = Modalconst emits = defineEmits(['confirm', 'cancel'])
const props = defineProps({title: {type: String,default: '提示'},vNode: {type: Object,default: null},footerVNode1: {type: Object,default: null},footerVNode2: {type: Object,default: null}
})const contentRef = ref()
const footerRef1 = ref()
const footerRef2 = ref()const visible = ref(false)
const description = ref('')
const btnLoading = ref(false)const openModel = value => {description.value = valuevisible.value = truenextTick(() => {if (props.vNode) {render(props.vNode, contentRef.value)}if (props.footerVNode1) {render(props.footerVNode1, footerRef1.value.$el)}if (props.footerVNode2) {render(props.footerVNode2, footerRef2.value.$el)}})
}const cancel = () => {btnLoading.value = falsevisible.value = falseemits('cancel')
}const confirm = () => {emits('confirm')
}defineExpose({openModel,cancel,btnLoading
})
</script>
<style lang="less" scoped></style>
2、同级目录下新建js文件,调用弹窗组件 src/components/ConfirmModal/index.js
import { createApp } from 'vue'
import ConfirmModal from './index.vue'export function showConfirmModal(vNode, footerVNode1, footerVNode2) {const div = document.createElement('div')document.body.appendChild(div)const app = createApp(ConfirmModal, { vNode, footerVNode1, footerVNode2 })const vm = app.mount(div)vm.openModel()return { app, vm }
}
3、在需要调用弹窗组件的js文件中引用 xxx.js
import { ref, h } from 'vue'
import { showConfirmModal } from '@/components/ConfirmModal/index.js'// 强制登录提示
const forceLogin = () => {localStorage.clear()showConfirmModal(h('div', { style: { color: '#333' } }, '你的账号在另一台设备登录,你将被迫下线,请确认密码是否泄露!'),null,h('div',{onClick: () => {window.location.reload()}},'确认'))
}
4、效果图