Skip to content

Commit 65443b7

Browse files
committed
fix: 修改Message基础使用 通过删除组件实例来清除组件并且重新计算其它Message的offset值
1 parent 924bb28 commit 65443b7

File tree

3 files changed

+65
-39
lines changed

3 files changed

+65
-39
lines changed

src/lib/message/src/message-method.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createVNode, render, ref } from "vue";
1+
import { createVNode, render, ref, VNode } from "vue";
22
import type { MessageQueue } from "./message";
33
import MessageConstructor from "./message.vue";
44
let seed = 1;
@@ -12,11 +12,15 @@ const message = function (options = {}) {
1212
});
1313

1414
const id = `message_${seed++}`;
15+
const userOnClose = (options as any).onClose;
1516
const props = {
1617
id,
1718
offset: verticalOffset,
1819
zIndex: zIndex.value++,
1920
...options,
21+
onClose: () => {
22+
close(id, userOnClose);
23+
},
2024
};
2125

2226
let appendTo: HTMLElement | null = document.body;
@@ -36,6 +40,33 @@ const message = function (options = {}) {
3640
render(vm, container);
3741
instances.push({ vm });
3842
appendTo.appendChild(container.firstElementChild!);
43+
44+
return {
45+
// instead of calling the onClose function directly, setting this value so that we can have the full lifecycle
46+
// for out component, so that all closing steps will not be skipped.
47+
close: () => ((vm.component!.proxy as any).visible = false),
48+
};
3949
};
4050

51+
export function close(id: string, userOnClose?: (vm: VNode) => void): void {
52+
const idx = instances.findIndex(({ vm }) => id === vm.component!.props.id);
53+
if (idx === -1) return;
54+
55+
const { vm } = instances[idx];
56+
if (!vm) return;
57+
userOnClose?.(vm);
58+
59+
const removedHeight = vm.el!.offsetHeight;
60+
instances.splice(idx, 1);
61+
62+
// adjust other instances vertical offset
63+
const len = instances.length;
64+
if (len < 1) return;
65+
for (let i = idx; i < len; i++) {
66+
const pos =
67+
parseInt(instances[i].vm.el!.style["top"], 10) - removedHeight - 16;
68+
69+
instances[i].vm.component!.props.offset = pos;
70+
}
71+
}
4172
export default message;

src/lib/message/src/message.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
import type { VNode } from "vue";
22

3+
export const messageProps = {
4+
duration: {
5+
type: Number,
6+
default: 3000,
7+
},
8+
id: {
9+
type: String,
10+
default: "",
11+
},
12+
offset: {
13+
type: Number,
14+
default: 100,
15+
},
16+
zIndex: {
17+
type: Number,
18+
default: 0,
19+
},
20+
onClose: {
21+
type: Function,
22+
required: false,
23+
},
24+
};
25+
26+
export const messageEmits = ["destory"];
27+
328
type MessageQueueItem = {
429
vm: VNode;
530
};

src/lib/message/src/message.vue

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
:duration="300"
44
leave-active-class="animate__zoomOut"
55
enter-active-class="animate__zoomIn"
6+
@before-leave="onClose"
7+
@after-leave="$emit('destory')"
68
>
79
<div
810
class="jw-message animate__animated"
@@ -16,36 +18,12 @@
1618
</template>
1719

1820
<script setup lang="ts">
19-
import {
20-
ref,
21-
onMounted,
22-
computed,
23-
watch,
24-
getCurrentInstance,
25-
nextTick,
26-
} from "vue";
27-
const props = defineProps({
28-
duration: {
29-
type: Number,
30-
default: 3000,
31-
},
32-
id: {
33-
type: String,
34-
default: "",
35-
},
36-
offset: {
37-
type: Number,
38-
default: 100,
39-
},
40-
zIndex: {
41-
type: Number,
42-
default: 0,
43-
},
44-
});
21+
import { ref, onMounted, computed } from "vue";
22+
import { messageProps, messageEmits } from "./message";
23+
const props = defineProps(messageProps);
24+
const emits = defineEmits(messageEmits);
4525
4626
const visible = ref(false);
47-
48-
const internalInstance = getCurrentInstance();
4927
const customStyle = computed(() => ({
5028
top: `${props.offset}px`,
5129
zIndex: props.zIndex,
@@ -67,15 +45,6 @@ onMounted(() => {
6745
startTimer();
6846
visible.value = true;
6947
});
70-
71-
watch(visible, () => {
72-
if (!visible.value) {
73-
setTimeout(() => {
74-
const el = internalInstance.vnode.el;
75-
el.parentNode.removeChild(el);
76-
}, 300);
77-
}
78-
});
7948
</script>
8049
<script lang="ts">
8150
export default {
@@ -102,6 +71,7 @@ export default {
10271
0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
10372
transition: color 0.3s var(--jw-bezier), box-shadow 0.3s var(--jw-bezier),
10473
background-color 0.3s var(--jw-bezier), opacity 0.3s var(--jw-bezier),
105-
transform 0.3s var(--jw-bezier), margin-bottom 0.3s var(--jw-bezier);
74+
transform 0.3s var(--jw-bezier), margin-bottom 0.3s var(--jw-bezier),
75+
top 0.3s var(--jw-bezier);
10676
}
10777
</style>

0 commit comments

Comments
 (0)