更多ruoyi-nbcio功能请看演示系统
gitee源代码地址
前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio
演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/
更多nbcio-boot功能请看演示系统
gitee源代码地址
后端代码: https://gitee.com/nbacheng/nbcio-boot
前端代码:https://gitee.com/nbacheng/nbcio-vue.git
在线演示(包括H5) : http://218.75.87.38:9888
接上一节
4、NModal.vue文件vue3修改如下:
<template> <a-modal :visible="visible" destroyOnClose > <slot></slot> <!--有设置标题--> <template v-if="!isNoTitle" #title> <a-row class="j-modal-title-row" type="flex"> <a-col class="left"> <slot name="title">{{ title }}</slot> </a-col> </a-row> </template> <!--没有设置标题--> <template v-else #title> <a-row class="j-modal-title-row" type="flex"> <a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen"> <a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon"/> </a-col> </a-row> </template> <!-- 处理 scopedSlots --> <template v-for="slotName of scopedSlotsKeys" :slot="slotName"> <slot :name="slotName"></slot> </template> <!-- 处理 slots --> <template v-for="slotName of slotsKeys" v-slot:[slotName]> <slot :name="slotName"></slot> </template> </a-modal> </template> <script setup lang="ts" name="NModal"> const props = defineProps({ title: String, // 可使用 .sync 修饰符 visible: Boolean, // 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符 fullscreen: { type: Boolean, default: false }, // 是否允许切换全屏(允许后右上角会出现一个按钮) switchFullscreen: { type: Boolean, default: false }, // 点击确定按钮的时候是否关闭弹窗 okClose: { type: Boolean, default: true } }) const instance = getCurrentInstance(); // 内部使用的 slots ,不再处理 const usedSlots = ref('title') const isNoTitle = computed(() => { return !props.title && !allSlotsKeys.includes('title') }) const slotsKeys = computed(() => { return Object.keys(instance.slots).filter(key => !usedSlots.value.includes(key)) }) const scopedSlotsKeys = computed(() => { return Object.keys(instance.slots).filter(key => !usedSlots.value.includes(key)) }) const allSlotsKeys = computed(() => { return Object.keys(instance.slots).concat(Object.keys(instance.slots)) }) </script> <style lang="less"> .j-modal-box { &.fullscreen { top: 0; left: 0; padding: 0; // 兼容1.6.2版本的antdv & .ant-modal { top: 0; padding: 0; height: 100vh; } & .ant-modal-content { height: 100vh; border-radius: 0; & .ant-modal-body { /* title 和 footer 各占 55px */ height: calc(100% - 55px - 55px); overflow: auto; } } &.no-title, &.no-footer { .ant-modal-body { height: calc(100% - 55px); } } &.no-title.no-footer { .ant-modal-body { height: 100%; } } } .j-modal-title-row { .left { width: calc(100% - 56px - 56px); } .right { width: 56px; position: inherit; .ant-modal-close { right: 56px; color: rgba(0, 0, 0, 0.45); &:hover { color: rgba(0, 0, 0, 0.75); } } } } &.no-title{ .ant-modal-header { padding: 0px 24px; border-bottom: 0px !important; } } } @media (max-width: 767px) { .j-modal-box.fullscreen { margin: 0; max-width: 100vw; } } </style>
5、DynamicNotice.vue文件vue3
<template> <component :is="comp" :formData="formData" ref="compModelRef" v-if="comp"> </component> </template> <script setup lang="ts" name="DynamicNotice"> const props = defineProps({ path : { type: String, }, formData : { type: Object, default: {}, } }) const compName = ref(props.path) const compModelRef = ref(null) const DyDetail = () => { setTimeout(() => { if(props.path){ compModelRef.value?.view(props.formData); } }, 200) } const comp = computed(() => { if(!props.path){ return null; } //去掉这个编译警告Critical dependency: the request of a dependency is an expression //return () => Promise.resolve(require(`@/views/${props.path}.vue`).default) return markRaw(defineAsyncComponent( () => import(/* @vite-ignore */`@/views/${props.path}.vue`).default)); }) //暴露detail方法 defineExpose({ DyDetail }); </script>
6、效果图如下: