vue3 把antd 的Modal组件作为子组件时,本地运行是没问题的,打包后 cancel关闭事件触发无效

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” 即可

岁月静好

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Vue3中,可以通过`ref`和`teleport`来实现父组件调用组件modal。 首先,在组件中,需要使用`teleport`将modal渲染到body中,这样可以避免modal被父组件的样式影响。代码如下: ```html <template> <teleport to="body"> <div class="modal"> <!-- modal内容 --> </div> </teleport> </template> ``` 然后,在父组件中,需要使用`ref`来获取组件的实例,并通过调用组件的方法来打开或关闭modal。代码如下: ```html <template> <div> <button @click="openModal">打开modal</button> <ChildComponent ref="childComponentRef" /> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent, }, methods: { openModal() { this.$refs.childComponentRef.openModal(); }, }, }; </script> ``` 在组件中,需要定义一个`openModal`方法来打开modal,并通过`emits`来向父组件发送事件。代码如下: ```html <template> <teleport to="body"> <div class="modal" v-if="visible"> <!-- modal内容 --> </div> </teleport> </template> <script> import { defineEmits } from 'vue'; export default { emits: ['update:visible'], data() { return { visible: false, }; }, methods: { openModal() { this.visible = true; this.$emit('update:visible', true); }, closeModal() { this.visible = false; this.$emit('update:visible', false); }, }, }; </script> ``` 在父组件中,需要通过`v-model`来监听组件的`visible`属性,并在组件的`update:visible`事件触发更新`visible`属性。代码如下: ```html <template> <div> <button @click="visible = true">打开modal</button> <ChildComponent v-model:visible="visible" /> </div> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent, }, data() { return { visible: false, }; }, }; </script> ``` 这样,就可以实现父组件调用组件modal了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值