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',