最近使用vue+elementUI做项目,自然少不了dialog这个组件的使用,关于dialog嵌套有两个小问题总结下。
1.dialog嵌套时,内层dialog上有遮罩层,无法点击。
关于这个,其实官方网站在介绍嵌套的dialog时也有提到:

正常情况下,我们不建议使用嵌套的 Dialog,如果需要在页面上同时显示多个 Dialog,可以将它们平级放置。对于确实需要嵌套
Dialog 的场景,我们提供了append-to-body属性。将内层 Dialog 的该属性设置为 true,它就会插入至 body
元素上,从而保证内外层 Dialog 和遮罩层级关系的正确。

内层的dialog在使用时,需要加上append-to-body属性,官方诗示例为: <el-dialog width="30%" title="内层 Dialog" :visible.sync="innerVisible" append-to-body> </el-dialog>

2.嵌套dialog为父子组件关系时,子组件(内层dialog)关闭后无法打开。关于这个问题,之前百度的方法都是在子组件监听父组件传过来的值,并在子组件的dialog执行close方法时,像父组件传递一个false的状态值。最近在查看官方有关计算属性的文档时,发现这个完全可以用计算属性解决,现将两种方法父子组件的代码分别示例,大家可根据个人习惯选择使用:
父组件代码段(两种方法相同):

<template>
  <div>
    <el-button type="primary" @click="outerVisible = true">点击打开外层 Dialog</el-button>
    <el-dialog title="外层 Dialog" :visible.sync="outerVisible">
      确定删除这条信息吗?
      <div slot="footer" class="dialog-footer">
        <el-button @click="outerVisible = false">取 消</el-button>
        <el-button type="primary" @click="innerVisible = true">确认</el-button>
      </div>
    </el-dialog>
    <child :innerVisible="innerVisible" v-on:innerDialog="getInnerStatus($event)"></child>
  </div>
</template>

<script>
import child from "./child";
export default {
  name: "father",
  components: { child },
  data() {
    return {
      outerVisible: false,
      innerVisible: false
    };
  },

  methods: {
    getInnerStatus(status) {
      this.innerVisible = status;
    }
  }
};
</script>

watch方法子组件代码:
说明:因为子组件中内的dialog状态需在true/false之间切换,而vue中不能直接在子组件中修改父组件传过来的值,所以需要重新定义一个变量openStatus来控制子组件中dialog的显示与否。
如果不重新定义变量接收父组件传过来的值,会提示如下错误:

Avoid mutating a prop directly since the value will be overwritten
whenever the parent component re-renders. Instead, use a data or
computed property based on the prop’s value. Prop being mutated:
“innerVisible”

<template>
  <el-dialog width="30%" title="内层 Dialog" :visible.sync="openStatus" append-to-body @close="doClose">
    <div slot="footer" class="dialog-footer">
      <el-button @click="openStatus = false">取 消</el-button>
      <el-button type="primary" @click="openStatus = false">确认</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: "child",
  props: {
    innerVisible: {
      type: Boolean,
      default: false,
    }
  },
  data() {
    return {
      openStatus: this.innerVisible,
    };
  },
  watch: {
    innerVisible(val) {
      this.openStatus = val;
    }
  },
  methods: {
    doClose() {
      this.$emit("innerDialog", false);
    }
  }
};
</script>

computed属性子组件代码段:

<template>
  <el-dialog width="30%" title="内层 Dialog" :visible.sync="openStatus" append-to-body>
    <div slot="footer" class="dialog-footer">
      <el-button @click="openStatus = false">取 消</el-button>
      <el-button type="primary" @click="openStatus = false">确认</el-button>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: "child",
  props: {
    innerVisible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {};
  },
  computed: {
    openStatus: {
      get() {
        return this.innerVisible;
      },
      set(val) {
        this.$emit("innerDialog", val);
      }
    }
  }
};
</script>

第一次写博客,不足之处多多,欢迎大家指正,谢谢~
就酱~~

Logo

前往低代码交流专区

更多推荐