diff --git a/components.js b/components.js
index 46e1d65dd..3cf7e5e4e 100644
--- a/components.js
+++ b/components.js
@@ -59,4 +59,5 @@ module.exports = [
'uploader',
'dropdown-menu',
'dropdown-item',
+ 'notify',
];
diff --git a/docs/markdown/changelog-v3.zh-CN.md b/docs/markdown/changelog-v3.zh-CN.md
index 354935c8d..7dae327d8 100644
--- a/docs/markdown/changelog-v3.zh-CN.md
+++ b/docs/markdown/changelog-v3.zh-CN.md
@@ -29,6 +29,7 @@ Vant 遵循 [Semver](https://semver.org/lang/zh-CN/) 语义化版本规范。
- ActionSheet
- Calendar
- Dialog
+- Notify
- Popup
- ShareSheet
diff --git a/src/notify/Notify.js b/src/notify/Notify.js
new file mode 100644
index 000000000..806878c30
--- /dev/null
+++ b/src/notify/Notify.js
@@ -0,0 +1,44 @@
+import { createNamespace } from '../utils';
+import { popupMixinProps } from '../mixins/popup';
+import Popup from '../popup';
+
+const [createComponent, bem] = createNamespace('notify');
+
+export default createComponent({
+ props: {
+ ...popupMixinProps,
+ color: String,
+ message: [Number, String],
+ duration: [Number, String],
+ className: null,
+ background: String,
+ getContainer: [String, Function],
+ type: {
+ type: String,
+ default: 'danger',
+ },
+ },
+
+ setup(props, { slots }) {
+ return () => {
+ const style = {
+ color: props.color,
+ background: props.background,
+ };
+
+ return (
+
+ {slots.default?.() || props.message}
+
+ );
+ };
+ },
+});
diff --git a/src/notify/Notify.tsx b/src/notify/Notify.tsx
deleted file mode 100644
index 35c99adc1..000000000
--- a/src/notify/Notify.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-// Utils
-import { createNamespace } from '../utils';
-import { inherit } from '../utils/functional';
-
-// Mixins
-import { popupMixinProps } from '../mixins/popup';
-
-// Components
-import Popup from '../popup';
-
-// Types
-import { CreateElement, RenderContext } from 'vue/types';
-import { DefaultSlots } from '../utils/types';
-import { PopupMixinProps } from '../mixins/popup/type';
-
-export type NotifyProps = PopupMixinProps & {
- type: 'primary' | 'success' | 'danger' | 'warning';
- color: string;
- message: number | string;
- duration: number | string;
- className?: any;
- background: string;
-};
-
-const [createComponent, bem] = createNamespace('notify');
-
-function Notify(
- h: CreateElement,
- props: NotifyProps,
- slots: DefaultSlots,
- ctx: RenderContext
-) {
- const style = {
- color: props.color,
- background: props.background,
- };
-
- return (
-
- {slots.default?.() || props.message}
-
- );
-}
-
-Notify.props = {
- ...popupMixinProps,
- color: String,
- message: [Number, String],
- duration: [Number, String],
- className: null as any,
- background: String,
- getContainer: [String, Function],
- type: {
- type: String,
- default: 'danger',
- },
-};
-
-export default createComponent(Notify);
diff --git a/src/notify/README.md b/src/notify/README.md
index 96ad5b187..2a50e6ba3 100644
--- a/src/notify/README.md
+++ b/src/notify/README.md
@@ -57,7 +57,7 @@ export default {
```html
-
+
Content
diff --git a/src/notify/README.zh-CN.md b/src/notify/README.zh-CN.md
index aed3d6aca..737eb5ec9 100644
--- a/src/notify/README.zh-CN.md
+++ b/src/notify/README.zh-CN.md
@@ -94,7 +94,7 @@ export default {
```html
-
+
通知内容
diff --git a/src/notify/demo/index.vue b/src/notify/demo/index.vue
index 79dbd37f2..e5ace9303 100644
--- a/src/notify/demo/index.vue
+++ b/src/notify/demo/index.vue
@@ -27,7 +27,7 @@
@click="showComponentCall"
/>
-
+
{{ t('content') }}
diff --git a/src/notify/index.js b/src/notify/index.js
new file mode 100644
index 000000000..7a3161b2f
--- /dev/null
+++ b/src/notify/index.js
@@ -0,0 +1,110 @@
+import { createApp, nextTick } from 'vue';
+import VanNotify from './Notify';
+import { isObject, inBrowser } from '../utils';
+
+let timer;
+let instance;
+
+function parseOptions(message) {
+ return isObject(message) ? message : { message };
+}
+
+function initInstance() {
+ const root = document.createElement('div');
+ document.body.appendChild(root);
+
+ instance = createApp({
+ data() {
+ return {
+ notifyProps: {
+ show: false,
+ },
+ };
+ },
+ methods: {
+ toggle(show) {
+ this.notifyProps.show = show;
+ },
+ setProps(props) {
+ this.notifyProps = props;
+ },
+ },
+ render() {
+ return (
+
+ );
+ },
+ }).mount(root);
+}
+
+function Notify(options) {
+ if (!inBrowser) {
+ return;
+ }
+
+ if (!instance) {
+ initInstance();
+ }
+
+ options = {
+ ...Notify.currentOptions,
+ ...parseOptions(options),
+ };
+
+ instance.setProps(options);
+ clearTimeout(timer);
+
+ if (options.duration && options.duration > 0) {
+ timer = setTimeout(Notify.clear, options.duration);
+ }
+
+ nextTick(() => {
+ instance.toggle(true);
+ });
+
+ return instance;
+}
+
+function defaultOptions() {
+ return {
+ type: 'danger',
+ message: '',
+ color: undefined,
+ background: undefined,
+ duration: 3000,
+ className: '',
+ onClose: null,
+ onClick: null,
+ onOpened: null,
+ };
+}
+
+Notify.clear = () => {
+ if (instance) {
+ instance.toggle(false);
+ }
+};
+
+Notify.currentOptions = defaultOptions();
+
+Notify.setDefaultOptions = (options) => {
+ Object.assign(Notify.currentOptions, options);
+};
+
+Notify.resetDefaultOptions = () => {
+ Notify.currentOptions = defaultOptions();
+};
+
+Notify.install = (app) => {
+ app.use(VanNotify);
+ app.config.globalProperties.$notify = Notify;
+};
+
+Notify.Component = VanNotify;
+
+export default Notify;
diff --git a/src/notify/index.ts b/src/notify/index.ts
deleted file mode 100644
index 44044b023..000000000
--- a/src/notify/index.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-import Vue from 'vue';
-import VanNotify from './Notify';
-import { isObject, isServer } from '../utils';
-import { mount } from '../utils/functional';
-import { NotifyOptions } from 'types/notify';
-
-let timer: number | NodeJS.Timeout;
-let instance: any;
-
-function parseOptions(message: NotifyOptions): NotifyOptions {
- return isObject(message) ? message : { message };
-}
-
-function Notify(options: NotifyOptions) {
- /* istanbul ignore if */
- if (isServer) {
- return;
- }
-
- if (!instance) {
- instance = mount(VanNotify, {
- on: {
- click(event: Event) {
- if (instance.onClick) {
- instance.onClick(event);
- }
- },
- close() {
- if (instance.onClose) {
- instance.onClose();
- }
- },
- opened() {
- if (instance.onOpened) {
- instance.onOpened();
- }
- },
- },
- });
- }
-
- options = {
- ...Notify.currentOptions,
- ...parseOptions(options),
- };
-
- Object.assign(instance, options);
- clearTimeout(timer as NodeJS.Timeout);
-
- if (options.duration && options.duration > 0) {
- timer = setTimeout(Notify.clear, options.duration);
- }
-
- return instance;
-}
-
-function defaultOptions(): NotifyOptions {
- return {
- type: 'danger',
- value: true,
- message: '',
- color: undefined,
- background: undefined,
- duration: 3000,
- className: '',
- onClose: null,
- onClick: null,
- onOpened: null,
- };
-}
-
-Notify.clear = () => {
- if (instance) {
- instance.value = false;
- }
-};
-
-Notify.currentOptions = defaultOptions();
-
-Notify.setDefaultOptions = (options: NotifyOptions) => {
- Object.assign(Notify.currentOptions, options);
-};
-
-Notify.resetDefaultOptions = () => {
- Notify.currentOptions = defaultOptions();
-};
-
-Notify.install = () => {
- Vue.use(VanNotify as any);
-};
-
-Notify.Component = VanNotify;
-
-Vue.prototype.$notify = Notify;
-
-export default Notify;
diff --git a/vant.config.js b/vant.config.js
index f96c2980f..e06b824a2 100644
--- a/vant.config.js
+++ b/vant.config.js
@@ -196,10 +196,10 @@ module.exports = {
path: 'loading',
title: 'Loading 加载',
},
- // {
- // path: 'notify',
- // title: 'Notify 消息通知',
- // },
+ {
+ path: 'notify',
+ title: 'Notify 消息通知',
+ },
{
path: 'overlay',
title: 'Overlay 遮罩层',
@@ -530,10 +530,10 @@ module.exports = {
path: 'loading',
title: 'Loading',
},
- // {
- // path: 'notify',
- // title: 'Notify',
- // },
+ {
+ path: 'notify',
+ title: 'Notify',
+ },
{
path: 'overlay',
title: 'Overlay',