Skip to content

Commit 44addc5

Browse files
committed
fix: 修改Message的基础使用
1 parent 65443b7 commit 44addc5

File tree

6 files changed

+101
-18
lines changed

6 files changed

+101
-18
lines changed

src/lib/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ const components = [
8282
JwSwitch,
8383

8484
JwAlert,
85-
JwMessage,
8685
JwDialog,
8786

8887
JwAffix,

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

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import { createVNode, render, ref, VNode } from "vue";
1+
import { createVNode, render, ref, VNode, isVNode } from "vue";
22
import type { MessageQueue } from "./message";
33
import MessageConstructor from "./message.vue";
44
let seed = 1;
55
const zIndex = ref(2000);
66
const instances: MessageQueue = [];
77

88
const message = function (options = {}) {
9+
if (typeof options === "string" || isVNode(options)) {
10+
options = { message: options };
11+
}
12+
913
let verticalOffset = 20;
1014
instances.forEach(({ vm }) => {
1115
verticalOffset += (vm.el?.offsetHeight || 0) + 16;
@@ -21,29 +25,42 @@ const message = function (options = {}) {
2125
onClose: () => {
2226
close(id, userOnClose);
2327
},
24-
};
28+
} as any;
2529

2630
let appendTo: HTMLElement | null = document.body;
31+
if (options.appendTo instanceof HTMLElement) {
32+
appendTo = options.appendTo;
33+
} else if (typeof options.appendTo === "string") {
34+
appendTo = document.querySelector(options.appendTo);
35+
}
36+
// should fallback to default value with a warning
37+
if (!(appendTo instanceof HTMLElement)) {
38+
throw new Error(
39+
"JwMessage the appendTo option is not an HTMLElement. Falling back to document.body."
40+
);
41+
appendTo = document.body;
42+
}
2743

2844
const container = document.createElement("div");
2945
container.className = `container_${id}`;
30-
const vm = createVNode(MessageConstructor, props, null);
3146

32-
// clean message element preventing mem leak
47+
const message = props.message;
48+
const vm = createVNode(
49+
MessageConstructor,
50+
props,
51+
isVNode(props.message) ? { default: () => message } : null
52+
);
53+
// 清除消息元素以防止内存泄漏
3354
vm.props!.onDestroy = () => {
3455
render(null, container);
35-
// since the element is destroy, then the VNode should be collected by GC as well
36-
// we do not want cause any mem leak because we have returned vm as a reference to users
37-
// so that we manually set it to false.
3856
};
3957

4058
render(vm, container);
4159
instances.push({ vm });
4260
appendTo.appendChild(container.firstElementChild!);
4361

4462
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.
63+
// 不是直接调用 onClose 函数,而是设置这个值,这样我们就可以拥有完整的生命周期
4764
close: () => ((vm.component!.proxy as any).visible = false),
4865
};
4966
};

src/lib/message/src/message.ts

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

3+
export const messageTypes = ["success", "info", "warning", "error"] as const;
4+
35
export const messageProps = {
46
duration: {
57
type: Number,
@@ -21,6 +23,15 @@ export const messageProps = {
2123
type: Function,
2224
required: false,
2325
},
26+
type: {
27+
type: String,
28+
values: messageTypes,
29+
default: "info",
30+
},
31+
message: {
32+
type: [String, Object],
33+
default: "",
34+
},
2435
};
2536

2637
export const messageEmits = ["destory"];

src/lib/message/src/message.vue

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,53 @@
1212
:style="customStyle"
1313
:id="id"
1414
>
15-
1 + 1 = ?
15+
<jw-icon
16+
class="jw-message-icon"
17+
:size="22"
18+
v-if="type === 'info'"
19+
color="#3f7ee8"
20+
>
21+
<Info24Filled />
22+
</jw-icon>
23+
<jw-icon
24+
class="jw-message-icon"
25+
:size="22"
26+
v-if="type === 'success'"
27+
color="#4b9e5f"
28+
>
29+
<IosCheckmarkCircle />
30+
</jw-icon>
31+
<jw-icon
32+
class="jw-message-icon"
33+
:size="22"
34+
v-if="type === 'warning'"
35+
color="#e4a341"
36+
>
37+
<WarningFilled />
38+
</jw-icon>
39+
<jw-icon
40+
class="jw-message-icon"
41+
:size="22"
42+
v-if="type === 'error'"
43+
color="#bf3f53"
44+
>
45+
<CloseCircle />
46+
</jw-icon>
47+
<slot>
48+
{{ message }}
49+
</slot>
1650
</div>
1751
</transition>
1852
</template>
1953

2054
<script setup lang="ts">
2155
import { ref, onMounted, computed } from "vue";
2256
import { messageProps, messageEmits } from "./message";
57+
import JwIcon from "@/lib/icon/index.vue";
58+
import { Info24Filled } from "@vicons/fluent";
59+
import { IosCheckmarkCircle } from "@vicons/ionicons4";
60+
import { WarningFilled } from "@vicons/carbon";
61+
import { CloseCircle } from "@vicons/ionicons5";
2362
const props = defineProps(messageProps);
2463
const emits = defineEmits(messageEmits);
2564
@@ -73,5 +112,9 @@ export default {
73112
background-color 0.3s var(--jw-bezier), opacity 0.3s var(--jw-bezier),
74113
transform 0.3s var(--jw-bezier), margin-bottom 0.3s var(--jw-bezier),
75114
top 0.3s var(--jw-bezier);
115+
116+
& .jw-message-icon {
117+
margin-right: 10px;
118+
}
76119
}
77120
</style>
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
<preview>基础使用</preview>
22
<template>
33
<jw-button @click="open">Show Message</jw-button>
4+
<jw-button @click="openVn">Vnode</jw-button>
45
</template>
56

67
<script setup lang="ts">
7-
import { ref } from "vue";
8+
import { ref, h } from "vue";
89
import JwMessage from "@/lib/message/index.ts";
910
1011
const open = () => {
11-
JwMessage();
12+
JwMessage("This is a Message");
1213
};
13-
const show = ref(false);
14-
</script>
1514
16-
<style scoped></style>
15+
const openVn = () => {
16+
JwMessage({
17+
message: h("p", null, [
18+
h("span", null, "Message can be "),
19+
h("i", { style: "color: teal" }, "VNode"),
20+
]),
21+
});
22+
};
23+
</script>

src/views/doc/message/index.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
</template>
1010

1111
<script setup lang="ts">
12-
import Preview from "@/components/Preview";
12+
import Preview from "@/components/Preview.vue";
1313
import MessagePreview1 from "./MessagePreview1.preview.vue";
1414
</script>
1515

16-
<style scoped></style>
16+
<style lang="scss">
17+
.message-doc-wrapper {
18+
.jw-button {
19+
margin-right: 8px;
20+
}
21+
}
22+
</style>

0 commit comments

Comments
 (0)