From 10355ed849f0e80382382793250938fbf8fb923a Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Mon, 31 Aug 2020 19:59:19 +0800 Subject: [PATCH] feat: add usePopupState --- src/dialog/index.js | 35 +++++++++++------------------- src/image-preview/index.js | 40 +++++++++++----------------------- src/notify/index.js | 29 +++++++------------------ src/toast/index.js | 17 ++++++++------- src/utils/index.ts | 17 --------------- src/utils/mount-component.ts | 42 ++++++++++++++++++++++++++++++++++++ 6 files changed, 84 insertions(+), 96 deletions(-) create mode 100644 src/utils/mount-component.ts diff --git a/src/dialog/index.js b/src/dialog/index.js index 9f977797c..59cb3dca8 100644 --- a/src/dialog/index.js +++ b/src/dialog/index.js @@ -1,38 +1,27 @@ import { nextTick } from 'vue'; -import { inBrowser, mountComponent } from '../utils'; +import { inBrowser } from '../utils'; +import { mountComponent, usePopupState } from '../utils/mount-component'; import VanDialog from './Dialog'; let instance; function initInstance() { - ({ instance } = mountComponent({ - data() { - return { - dialogProps: { - show: false, - }, - }; - }, - methods: { - toggle(show) { - this.dialogProps.show = show; - }, - setProps(props) { - this.dialogProps = props; - }, - }, - render() { - return ( + const Wrapper = { + setup() { + const { state, toggle } = usePopupState(); + return () => ( ); }, - })); + }; + + ({ instance } = mountComponent(Wrapper)); } function Dialog(options) { @@ -46,7 +35,7 @@ function Dialog(options) { initInstance(); } - instance.setProps({ + instance.setState({ ...Dialog.currentOptions, ...options, callback: (action) => { diff --git a/src/image-preview/index.js b/src/image-preview/index.js index db17898e6..61e6a88ef 100644 --- a/src/image-preview/index.js +++ b/src/image-preview/index.js @@ -1,5 +1,6 @@ import { nextTick } from 'vue'; -import { inBrowser, mountComponent } from '../utils'; +import { inBrowser } from '../utils'; +import { mountComponent, usePopupState } from '../utils/mount-component'; import VanImagePreview from './ImagePreview'; let instance; @@ -27,34 +28,19 @@ const defaultConfig = { function initInstance() { ({ instance } = mountComponent({ - data() { - return { - props: { - show: false, - }, + setup() { + const { state, toggle } = usePopupState(); + + const onClosed = () => { + state.images = []; }; - }, - methods: { - close() { - this.toggle(false); - }, - toggle(show) { - this.props.show = show; - }, - setProps(props) { - Object.assign(this.props, props); - }, - onClosed() { - this.props.images = []; - }, - }, - render() { - return ( + + return () => ( ); @@ -74,7 +60,7 @@ const ImagePreview = (images, startPosition = 0) => { const options = Array.isArray(images) ? { images, startPosition } : images; - instance.setProps({ + instance.setState({ ...defaultConfig, ...options, }); diff --git a/src/notify/index.js b/src/notify/index.js index 8a33a00ca..3cb333547 100644 --- a/src/notify/index.js +++ b/src/notify/index.js @@ -1,5 +1,6 @@ import { nextTick } from 'vue'; -import { isObject, inBrowser, mountComponent } from '../utils'; +import { isObject, inBrowser } from '../utils'; +import { mountComponent, usePopupState } from '../utils/mount-component'; import VanNotify from './Notify'; let timer; @@ -11,27 +12,13 @@ function parseOptions(message) { function initInstance() { ({ instance } = mountComponent({ - data() { - return { - notifyProps: { - show: false, - }, - }; - }, - methods: { - toggle(show) { - this.notifyProps.show = show; - }, - setProps(props) { - this.notifyProps = props; - }, - }, - render() { - return ( + setup() { + const { state, toggle } = usePopupState(); + return () => ( ); @@ -53,7 +40,7 @@ function Notify(options) { ...parseOptions(options), }; - instance.setProps(options); + instance.setState(options); clearTimeout(timer); if (options.duration && options.duration > 0) { diff --git a/src/toast/index.js b/src/toast/index.js index 6511a5b50..947285b69 100644 --- a/src/toast/index.js +++ b/src/toast/index.js @@ -1,5 +1,6 @@ import { nextTick } from 'vue'; -import { isObject, inBrowser, mountComponent } from '../utils'; +import { isObject, inBrowser } from '../utils'; +import { mountComponent } from '../utils/mount-component'; import VanToast from './Toast'; const defaultOptions = { @@ -57,14 +58,14 @@ function createInstance() { return { timer: null, message: null, - toastProps: { + state: { show: false, }, }; }, watch: { message(val) { - this.toastProps.message = val; + this.state.message = val; }, }, methods: { @@ -72,7 +73,7 @@ function createInstance() { this.toggle(false); }, toggle(show, duration) { - this.toastProps.show = show; + this.state.show = show; if (show) { clearTimeout(this.timer); @@ -84,8 +85,8 @@ function createInstance() { } } }, - setProps(props) { - this.toastProps = { + setState(props) { + this.state = { ...props, duration: undefined, }; @@ -102,7 +103,7 @@ function createInstance() { return ( { toast.toggle(true, options.duration); diff --git a/src/utils/index.ts b/src/utils/index.ts index 06ec441d9..e461e855a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,5 +1,3 @@ -import { createApp, Component } from 'vue'; - export { addUnit, getSizeStyle } from './format/unit'; export { createNamespace } from './create'; @@ -42,18 +40,3 @@ export function pick(obj: Record, keys: string[]) { return ret; }, {} as Record); } - -export function mountComponent(RootComponent: Component) { - const app = createApp(RootComponent); - const root = document.createElement('div'); - - document.body.appendChild(root); - - return { - instance: app.mount(root), - unmount() { - app.unmount(root); - document.body.removeChild(root); - }, - }; -} diff --git a/src/utils/mount-component.ts b/src/utils/mount-component.ts new file mode 100644 index 000000000..5c20326ab --- /dev/null +++ b/src/utils/mount-component.ts @@ -0,0 +1,42 @@ +import { createApp, reactive, Component } from 'vue'; +import { usePublicApi } from '../composition/use-public-api'; + +export function usePopupState() { + const state = reactive({ + show: false, + }); + + const toggle = (show: boolean) => { + state.show = show; + }; + + const close = () => { + toggle(false); + }; + + const setState = (props: Record) => { + Object.assign(state, props); + }; + + usePublicApi({ close, toggle, setState }); + + return { + state, + toggle, + }; +} + +export function mountComponent(RootComponent: Component) { + const app = createApp(RootComponent); + const root = document.createElement('div'); + + document.body.appendChild(root); + + return { + instance: app.mount(root), + unmount() { + app.unmount(root); + document.body.removeChild(root); + }, + }; +}