mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-23 18:00:27 +08:00
feat: add usePopupState
This commit is contained in:
parent
f0675d043a
commit
10355ed849
@ -1,38 +1,27 @@
|
|||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
import { inBrowser, mountComponent } from '../utils';
|
import { inBrowser } from '../utils';
|
||||||
|
import { mountComponent, usePopupState } from '../utils/mount-component';
|
||||||
import VanDialog from './Dialog';
|
import VanDialog from './Dialog';
|
||||||
|
|
||||||
let instance;
|
let instance;
|
||||||
|
|
||||||
function initInstance() {
|
function initInstance() {
|
||||||
({ instance } = mountComponent({
|
const Wrapper = {
|
||||||
data() {
|
setup() {
|
||||||
return {
|
const { state, toggle } = usePopupState();
|
||||||
dialogProps: {
|
return () => (
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggle(show) {
|
|
||||||
this.dialogProps.show = show;
|
|
||||||
},
|
|
||||||
setProps(props) {
|
|
||||||
this.dialogProps = props;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<VanDialog
|
<VanDialog
|
||||||
lazyRender={false}
|
lazyRender={false}
|
||||||
{...{
|
{...{
|
||||||
...this.dialogProps,
|
...state,
|
||||||
'onUpdate:show': this.toggle,
|
'onUpdate:show': toggle,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}));
|
};
|
||||||
|
|
||||||
|
({ instance } = mountComponent(Wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
function Dialog(options) {
|
function Dialog(options) {
|
||||||
@ -46,7 +35,7 @@ function Dialog(options) {
|
|||||||
initInstance();
|
initInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.setProps({
|
instance.setState({
|
||||||
...Dialog.currentOptions,
|
...Dialog.currentOptions,
|
||||||
...options,
|
...options,
|
||||||
callback: (action) => {
|
callback: (action) => {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
import { inBrowser, mountComponent } from '../utils';
|
import { inBrowser } from '../utils';
|
||||||
|
import { mountComponent, usePopupState } from '../utils/mount-component';
|
||||||
import VanImagePreview from './ImagePreview';
|
import VanImagePreview from './ImagePreview';
|
||||||
|
|
||||||
let instance;
|
let instance;
|
||||||
@ -27,34 +28,19 @@ const defaultConfig = {
|
|||||||
|
|
||||||
function initInstance() {
|
function initInstance() {
|
||||||
({ instance } = mountComponent({
|
({ instance } = mountComponent({
|
||||||
data() {
|
setup() {
|
||||||
return {
|
const { state, toggle } = usePopupState();
|
||||||
props: {
|
|
||||||
show: false,
|
const onClosed = () => {
|
||||||
},
|
state.images = [];
|
||||||
};
|
};
|
||||||
},
|
|
||||||
methods: {
|
return () => (
|
||||||
close() {
|
|
||||||
this.toggle(false);
|
|
||||||
},
|
|
||||||
toggle(show) {
|
|
||||||
this.props.show = show;
|
|
||||||
},
|
|
||||||
setProps(props) {
|
|
||||||
Object.assign(this.props, props);
|
|
||||||
},
|
|
||||||
onClosed() {
|
|
||||||
this.props.images = [];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<VanImagePreview
|
<VanImagePreview
|
||||||
{...{
|
{...{
|
||||||
...this.props,
|
...state,
|
||||||
onClosed: this.onClosed,
|
onClosed,
|
||||||
'onUpdate:show': this.toggle,
|
'onUpdate:show': toggle,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -74,7 +60,7 @@ const ImagePreview = (images, startPosition = 0) => {
|
|||||||
|
|
||||||
const options = Array.isArray(images) ? { images, startPosition } : images;
|
const options = Array.isArray(images) ? { images, startPosition } : images;
|
||||||
|
|
||||||
instance.setProps({
|
instance.setState({
|
||||||
...defaultConfig,
|
...defaultConfig,
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { nextTick } from 'vue';
|
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';
|
import VanNotify from './Notify';
|
||||||
|
|
||||||
let timer;
|
let timer;
|
||||||
@ -11,27 +12,13 @@ function parseOptions(message) {
|
|||||||
|
|
||||||
function initInstance() {
|
function initInstance() {
|
||||||
({ instance } = mountComponent({
|
({ instance } = mountComponent({
|
||||||
data() {
|
setup() {
|
||||||
return {
|
const { state, toggle } = usePopupState();
|
||||||
notifyProps: {
|
return () => (
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggle(show) {
|
|
||||||
this.notifyProps.show = show;
|
|
||||||
},
|
|
||||||
setProps(props) {
|
|
||||||
this.notifyProps = props;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<VanNotify
|
<VanNotify
|
||||||
{...{
|
{...{
|
||||||
...this.notifyProps,
|
...state,
|
||||||
'onUpdate:show': this.toggle,
|
'onUpdate:show': toggle,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -53,7 +40,7 @@ function Notify(options) {
|
|||||||
...parseOptions(options),
|
...parseOptions(options),
|
||||||
};
|
};
|
||||||
|
|
||||||
instance.setProps(options);
|
instance.setState(options);
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
|
|
||||||
if (options.duration && options.duration > 0) {
|
if (options.duration && options.duration > 0) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { nextTick } from 'vue';
|
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';
|
import VanToast from './Toast';
|
||||||
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
@ -57,14 +58,14 @@ function createInstance() {
|
|||||||
return {
|
return {
|
||||||
timer: null,
|
timer: null,
|
||||||
message: null,
|
message: null,
|
||||||
toastProps: {
|
state: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
message(val) {
|
message(val) {
|
||||||
this.toastProps.message = val;
|
this.state.message = val;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -72,7 +73,7 @@ function createInstance() {
|
|||||||
this.toggle(false);
|
this.toggle(false);
|
||||||
},
|
},
|
||||||
toggle(show, duration) {
|
toggle(show, duration) {
|
||||||
this.toastProps.show = show;
|
this.state.show = show;
|
||||||
|
|
||||||
if (show) {
|
if (show) {
|
||||||
clearTimeout(this.timer);
|
clearTimeout(this.timer);
|
||||||
@ -84,8 +85,8 @@ function createInstance() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setProps(props) {
|
setState(props) {
|
||||||
this.toastProps = {
|
this.state = {
|
||||||
...props,
|
...props,
|
||||||
duration: undefined,
|
duration: undefined,
|
||||||
};
|
};
|
||||||
@ -102,7 +103,7 @@ function createInstance() {
|
|||||||
return (
|
return (
|
||||||
<VanToast
|
<VanToast
|
||||||
{...{
|
{...{
|
||||||
...this.toastProps,
|
...this.state,
|
||||||
onClosed: this.onClosed,
|
onClosed: this.onClosed,
|
||||||
'onUpdate:show': this.toggle,
|
'onUpdate:show': this.toggle,
|
||||||
}}
|
}}
|
||||||
@ -132,7 +133,7 @@ function Toast(options = {}) {
|
|||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
|
|
||||||
toast.setProps(options);
|
toast.setState(options);
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
toast.toggle(true, options.duration);
|
toast.toggle(true, options.duration);
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import { createApp, Component } from 'vue';
|
|
||||||
|
|
||||||
export { addUnit, getSizeStyle } from './format/unit';
|
export { addUnit, getSizeStyle } from './format/unit';
|
||||||
export { createNamespace } from './create';
|
export { createNamespace } from './create';
|
||||||
|
|
||||||
@ -42,18 +40,3 @@ export function pick(obj: Record<string, any>, keys: string[]) {
|
|||||||
return ret;
|
return ret;
|
||||||
}, {} as Record<string, any>);
|
}, {} as Record<string, any>);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
42
src/utils/mount-component.ts
Normal file
42
src/utils/mount-component.ts
Normal file
@ -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<string, any>) => {
|
||||||
|
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);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user