1、需求,点击一个按钮,弹窗出现,把弹窗当作子组件
// 父组件
<template>
<div class="map-pop">
<header>
<span>{{siteInfo.name||'--'}}</span>
<CloseOutlined class="close" @click="close"/>
</header>
<body>
<ul class="info">
<li>
<span>测站编码:</span>
<em>{{siteInfo.code||'--'}}</em>
</li>
<li>
<span>测站类型:</span>
<em>{{siteInfo.typeName||'--'}}</em>
</li>
<li>
<span>行政区域:</span>
<em>{{siteInfo.region||'--'}}</em>
</li>
<li>
<span>上报时间:</span>
<em>{{siteInfo.reportTime||'--'}}</em>
</li>
<li v-for="(i,index) in siteInfo.dataList" :key="index">
<span>{{i.dataItem}}:</span>
<em>{{i.dataVal}}</em>
</li>
</ul>
<div class="carth">
<div>
<a-tooltip title="故障率">
<a-progress
strokeColor="#1890FC"
trailColor="#B3C5F7"
:format="percent=>h('div',{class:'prog-tips',style:'color:#1890FC'},[`${percent}%`,h('p',{},'故障率')])"
:strokeWidth="10" strokeLinecap="round" :percent="siteInfo.faultRate||0" type="circle" :width="64" />
</a-tooltip>
<a-tooltip title="置换率">
<a-progress
strokeColor="#F8651F"
trailColor="#B3C5F7"
:format="percent=>h('div',{class:'prog-tips',style:'color:#F8651F'},[`${percent}%`,h('p',{},'置换率')])"
:strokeWidth="10" strokeLinecap="round" :percent="siteInfo.displaceRate||0" type="circle" :width="64" />
</a-tooltip>
</div>
<a-button type="primary" class="see" @click="handleDetail">查看详情</a-button>
</div>
</body>
<siteInfoPop
v-model:visible="showSitePop"
:info="siteInfo"
ref="siteRef"
/>
</div>
</template>
<script setup>
import siteInfoPop from "./siteInfoPop.vue";
import {CloseOutlined} from '@ant-design/icons-vue';
import { nextTick, ref, h } from 'vue';
let showSitePop = ref(false);
const emit = defineEmits(['close']);
const siteRef = ref(null);
const props = defineProps({
siteInfo:{
type:Object,
default:{}
}
})
const handleDetail = () => {
showSitePop.value = true;
nextTick(() => {
siteRef.value.getData();
})
};
const close = ()=>{
emit('close')
}
</script>
<style scoped lang="less">
.map-pop{
color: #262626;border-radius:15px;
header{display: flex;height:36px;background:#CAEEFF;padding:0 16px;
display: flex;align-items: center;justify-content: space-between;
.close{
&:hover{color: #1890FC}
}
}
body{
padding:12px 16px;
.info{
li{width: 50%;}
font-size: 12px;
display: flex;align-items: center;justify-content:space-between;
flex-wrap: wrap;margin-bottom: 14px;
em{color: #595959}
}
}
.see{border-radius: 15px;}
}
.carth{
display: flex;align-items: center;justify-content:space-between;
div{
&:first-child{margin-right: 16px;}
}
}
:deep(.ant-progress-text){
.prog-tips{font-size:13px;
p{transform: scale(0.76);margin-top: 4px;color: #595959;}
}
}
</style>
2、子组件a-modal 使用 v-model:visible=“visible”
// 子组件
<template>
<div class="">
<a-modal
v-model:visible="visible"
@cancel="cancel"
:footer="null"
class="siteInfoPop"
:width="1400"
>
<template #title>
<span class="info-title">{{ info.address }}</span>
<span class="site-status" :class="{'inline-status': info.status == 1, 'alarm-status': info.status == 2, 'offline-status': info.status == 3, 'warm-status': info.status == 4 }">{{ info.status == 1? '在线': info.status == 2?'告警': info.status == 3? '离线': '预警' }}</span>
</template>
<div class="title-box">
<a-radio-group v-model:value="mode">
<a-radio-button value="1">基础信息</a-radio-button>
<a-radio-button value="2">监测数据</a-radio-button>
<a-radio-button value="3">告警信息</a-radio-button>
<a-radio-button value="4">态势分析</a-radio-button>
<a-radio-button value="5">工况曲线</a-radio-button>
</a-radio-group>
</div>
<div class="content-box">
<baseInfo :siteId="info.id" ref="baseRef" v-if="mode == '1'"/>
<monitorData :siteId="info.id" v-if="mode == '2'"/>
<alarmInfo :siteId="info.id" v-if="mode == '3'"/>
<analysisInfo :siteId="info.id" v-if="mode == '4'"/>
<workInfo :siteId="info.id" v-if="mode == '5'"/>
</div>
</a-modal>
</div>
</template>
<script setup>
import baseInfo from "./baseInfo.vue";
import monitorData from "./monitorData.vue";
import alarmInfo from "./alarmInfo.vue";
import analysisInfo from "./analysisInfo.vue";
import workInfo from "./workInfo.vue";
import { nextTick, ref } from "vue";
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
info: {
type: Object,
default: {},
},
});
let mode = ref("1");
const baseRef = ref(null);
const getData = () => {
mode.value = "1";
nextTick(() => {
baseRef.value.getData();
})
};
const emit = defineEmits(['update:visible']);
//取消事件
const cancel = () => {
emit('update:visible',false)
};
defineExpose({
getData
})
</script>
<style scoped lang="less">
.siteInfoPop {
.info-title {
font-weight: 600;
margin-right: 10px;
}
.site-status {
color: #fff;
padding: 0.01rem 0.1rem;
border-radius: 0.1rem;
}
.inline-status {
background: #1890FC;
}
.alarm-status {
background: #f67777;
}
.offline-status {
background: #9f9f9f;
}
.warm-status {
background: #f8c24b;
}
.title-box {
text-align: center;
}
:deep(.ant-modal-content) {
border-radius: 20px;
}
:deep(.ant-modal-content .ant-modal-header) {
border-radius: 20px 20px 0 0;
}
}
</style>
3、在本地运行都没啥问题的,也不报错,但是打包后,点击取消按钮,报错visible未定义,且弹窗未关闭,解决:把 v-model:visible=“visible” 改成 :visible=“visible” 即可
岁月静好