文章

Vue3封装全局通用提示弹窗-结合el-dialog

Vue3封装全局通用提示弹窗(结合el-dialog)

Vue3封装全局通用提示弹窗(结合el-dialog)

const createMount = (opts: any) => { if (mountNode) {//确保只存在一个弹框 document.body.removeChild(mountNode) mountNode = null } mountNode = document.createElement(‘div’) document.body.appendChild(mountNode) const app: any = createApp(SubDialog, { …opts, modeValue: true, remove() { //传入remove函数,组件内可移除dom 组件内通过props接收 app.unmount(mountNode) document.body.removeChild(mountNode) } }) return app.mount(mountNode) }

function V3Popup(options: any = {}) { options.id = options.id || ‘v3popup_’ + 1 //唯一id 删除组件时用于定位 return createMount(options) }

V3Popup.install = (app: any) => { app.component(‘ConfirmDialog’, SubDialog);// 全局注册 - 组件式 app.config.globalProperties.$confirmDialog = V3Popup;// 全局注册 - 函数式 } export default V3Popup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150


```vue
<!--
@component  通用提示弹窗
@date  2022.11.25

使用方法:
1)组件式
<ConfirmDialog
  title="标题"
  message="消息内容"
  v-model="testVisible"
  @confirm="testConfirm"
  @cancel="testCancel"
/>

2)函数式 - vue-class-component
import {getCurrentInstance} from 'vue';
const currentInstance = getCurrentInstance();
const {proxy: {$confirmDialog}}: any = this.currentInstance;
$confirmDialog({
  title: '标题',
  message: '消息内容',
  cancel: () => {
    console.log('取消')
  },
  confirm: () => {
    console.log('确认')
  },
});
-->

<template>
  <el-dialog
    class="confirmDialog"
    :width="width"
    :model-value="visible"
    :before-close="handleClose"
    :destroy-on-close="true"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <template #header>

      <div class="my-header">{{ title }}</div>

    </template>

    <div class="content">{{ message }}</div>

    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="confirmFn">确认</el-button>
        <el-button @click="cancelFn">取消</el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import {ref, defineProps, defineEmits} from "vue";

const props = defineProps({
  title: {
    type: String,
    default: "信息提示",
  },
  message: {
    type: String,
    default: "确定取消吗?",
  },
  width: {
    type: String,
    default: "400px",
  },
  // 必须为 modelValue
  modelValue: {
    type: Boolean,
    default: true,
  },
  cancel: {
    type: Function,
    default: () => {
      console.log()
    }
  },
  confirm: {
    type: Function,
    default: () => {
      console.log()
    },
  },
});
// 此处 emit 兼容组件式用法,其它为函数式用法
const emit = defineEmits(['cancel', 'confirm', 'update:modelValue']);
const visible = ref(true); // 窗体显示控制

const cancelFn = () => {
  props.cancel();
  emit('cancel');
  visible.value = false;
  emit('update:modelValue', false);
};

const confirmFn = () => {
  props.confirm();
  emit('confirm');
  visible.value = false;
  // emit('update:modelValue', false); // 关闭操作留给页面
};

const handleClose = (done: any) => {
  done();
}
</script>

<!--
自定义dialog样式
-->
<style>
.confirmDialog.el-dialog {
  border-radius: 10px;
}

.confirmDialog .el-dialog__header {
  margin: 0;
  padding: 0;
}
</style>

<style lang="scss" scoped>
.confirmDialog {
  .my-header {
    height: 50px;
    line-height: 50px;
    background: #F8F8F8;
    padding: 0 18px;
    font-size: 18px;
    color: #303133;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
  }

  .content {
    font-size: 16px;
  }
}
</style>

本文由作者按照 CC BY 4.0 进行授权

© 独行的风. 保留部分权利。

本站采用 Jekyll 主题 Chirpy

本站总访问量 本站访客数 本文阅读量