vue3弹窗没有正确的弹出来,如何找出问题所在?

问题描述

问题中的弹窗组件是封装后的组件,目的是 promise 式调用

改弹窗的原理是有一个div容器容纳所有弹窗(v-for遍历) 遍历的弹框数据保存起来,利用的是component 的is 属性 将component动态赋值给 遍历项

该弹窗在vue2是正常运行的,升级vue3后,本地环境是可以弹出来的,但是在部署到线上环境后弹不出来 且没有任何警告或者报错

问题出现的环境背景及自己尝试过哪些方法

问题背景 vue2 升级 vue3,该组件为 vue2 的公共组件,升级 vue3 后出现问题,线上环境的弹窗弹不出来,测试后弹窗的生命周期钩子都有打印

下列截图为打印容器portal保存的comp,
个人猜测是线上环境没有 render 属性 才导致的没有正常弹出,但是为什么会没有render呢,本地明明有这个属性

线上环境(没有正常显示的弹窗组件的打印)
image.png

本地环境(正常弹出的弹窗组件的打印)
image.png

但是同一套代码部署到线上为什么会出现这种情况

相关代码

粘贴代码文本(请勿用截图)

portal容器
<template>
  <div class="c-portal-container">
    <component
      :is="item.comp"
      v-for="(item,index) in list"
      :key="item.key"
      v-bind="item.props"
      @close="list[index].close"
      @sure="list[index].sure"
    />
  </div>
</template>
<script>
import { markRaw, reactive, ref } from 'vue';

let i = 1;
const getUid = () => i++;
const list = reactive([]);
const itemRefs = ref([]);
let vm;
/**
 * 传送门
 *
 */
export class Portal{
  constructor(comp, option = {}){
    console.log('comp: ', comp);
    if (!comp) throw new Error('portal 的 Component 必传');
    if (!comp.name) throw new Error('portal 的 Component.name 必传');
    this.comp = markRaw(comp);
    this.option = option;
  }
  popup(props = {}, option = {  }){
    const { single = false } = { ...this.option, ...option };

    return new Promise((resolve, reject) => {
      const key = single ?  this.comp.name : getUid();
      const listItem = {
        comp: this.comp,
        props,
        option,
        key,
        close(data) {
          listItem.remove();
          reject(data);
        },
        sure(data){
          listItem.remove();
          resolve(data);
        },
        remove(){
          setTimeout(() => {
            const index = list.indexOf(this);
            if (index > -1){
              list.splice(index, 1);
            }
          }, 300);
        },
        removeImmediately(){
          const index = list.indexOf(this);
          if (index > -1){
            list.splice(index, 1);
          }
        },
 
      };
      if (props.getPortal){
        props.getPortal(listItem);
        delete props.getPortal;
      }

      const index = list.findIndex(item => item.key === listItem.key);
      if (index === -1){
        list.push(listItem);
      } else {
        const removedItem = list.splice(index, 1, listItem)[0];
      }
    });
 
  }


export default {
  name: 'c-portal-container',
  components: {
  },
  props: {
  },
  data() {
    return {
      list
    };
  },
  created(){
    vm = this;
  },
  methods: {
  }
};
</script>
<style lang="scss">
</style>

封装

<template>
  <el-dialog
    v-model="visible"
    :title="title"
    top="30vh"
        
    width="320px"
    class="c-confirm"
    @close="handleCancel"
  >
   

  </el-dialog>
</template>
<script>
import { Portal } from "./Portal.vue";
const comp = {
  name: "c-confirm",


 
  mounted(){
    this.visible = true;
  },
    
  methods: {
    close(result){
      this.visible = false;
      this.$emit("sure", result);
    },
    handleOk(){
      if (this.onOk){
        this.loading = true;
        this.onOk()
          .then((res) => res !== false && this.close(true))
          .catch(e => e && console.error(e))
          .finally(() => this.loading = false);
      } else {
        this.close(true);
      }
            
    },
    handleCancel(){
      this.visible = false;
      this.$emit("close");
    }
  }
};
export default comp;
export const Confirm = new Portal(comp);
export const portal = Confirm;

</script>

使用

      this.$Confirm.popup({
        title: "",
        subTitle: ``
      }).then(() => {
        this.$post
        });
      }).catch(e => e && console.log(e));

你期待的结果是什么?实际看到的错误信息又是什么?


更新
个人发现export 的问题
如果使用module.export comp

然后使用的时候再new Portal(comp)就可以修复
但是在vue3中为什么只能module.export

阅读 1.8k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题