更多ruoyi-nbcio功能请看演示系统
gitee源代码地址
前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio
演示地址:RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/
更多nbcio-boot功能请看演示系统
gitee源代码地址
后端代码: https://gitee.com/nbacheng/nbcio-boot
前端代码:https://gitee.com/nbacheng/nbcio-vue.git
在线演示(包括H5) : http://122.227.135.243:9888
接上一节
4、NModal.vue文件vue3修改如下:
javascript
<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
javascript
<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、效果图如下: