An open API service indexing awesome lists of open source software.

https://github.com/shunnnet/vue-use-modal-context

Vue modal helpers for simplify modal usage
https://github.com/shunnnet/vue-use-modal-context

Last synced: about 1 year ago
JSON representation

Vue modal helpers for simplify modal usage

Awesome Lists containing this project

README

          

# vue-use-modal-context
[繁體中文](./README.zh-tw.md)

This is a tool that makes using modals more convenient by using [Vue 3 `provide` / `inject`](https://vuejs.org/guide/components/provide-inject.html). Please familiarize yourself with it before use.

It provides a simpler way to toggle modals and pass data. It should reduce some of the work when configuring modals.

Supports Vue 3+.

Excludes the modal itself. If you're choosing a modal package, you might consider [vue-final-modal](https://github.com/vue-final/vue-final-modal)。

- [vue-use-modal-context](#vue-use-modal-context)
- [Install](#install)
- [Tutorial](#tutorial)
- [Tutorial - global context](#tutorial---global-context)
- [setup global modal](#setup-global-modal)
- [documentation](#documentation)
- [`useModalContext` and ``](#usemodalcontext-and-modalcontext)
- [``](#modalcontext)
- [`useModalProvider` and ``](#usemodalprovider-and-modalprovider)
- [`useModalProvider`](#usemodalprovider)
- [`useGlobalModalContext`](#useglobalmodalcontext)
- [Types](#types)
- [Global components type](#global-components-type)

## Install
```sh
npm install vue-use-modal-context
```

You can globally register the component ``, `` using a plugin. (`component: true`)

```ts
import { ModalContextPlugin } from "vue-use-modal-context"

const app = createApp(App)

app.use(ModalContextPlugin, { component: true })

app.mount('#app')
```

Alternatively, you can also import it directly.

```ts
import { ModalContext, ModalProvider } from "vue-use-modal-context"
```

[setup global component type](#global-components-type)

## Tutorial
First, let's take a look at a typical example of using a modal.

This is a situation I often encounter: to set up a modal, I need to configure show, `openModal`, `modalData`, and so on. If there are 10 modals, I have to set it up 10 times.

```vue

import { ref } from 'vue'

const show = ref(false)
const modalData = ref({
userId: 0
})

const openModal = (userId) => {
show.value = true
modalData.userId = userId
}

const onModalClose = () => {
modalData.userId = 0
}


Show user



```

Now, let's try using the tools provided by `vue-use-modal-context`, namely `useModalContext` and `ModalProvider`, to simplify this example. First, call `useModalContext()`, and you can obtain `openModal`.

```vue

import { useModalContext, ModalProvider } from "vue-use-modal-context"

const { openModal } = useModalContext()



```

Next, you need to add `ModalProvider` to register a modal with the `modalContext`. We registered a modal with the name **UserModal**.

```vue

import { useModalContext, ModalProvider } from "vue-use-modal-context"

const { openModal } = useModalContext()



```

Next, you can retrieve the modal's state from the `scoped slot` of `ModalProvider`, which includes `show` and `data`. Connect these two pieces of data to the modal and set the initial data to `init-data`.

```vue

import { useModalContext, ModalProvider } from "vue-use-modal-context"

const { openModal } = useModalContext()





```

Finally, just add the button to open the modal and bind it to `openModal`.

```vue

import { useModalContext, ModalProvider } from "vue-use-modal-context"

const { openModal } = useModalContext()


Show user



```

If you want to add a new modal, you just need to register a new `ModalProvider`.

```vue

import { useModalContext, ModalProvider } from "vue-use-modal-context"

const { openModal } = useModalContext()


Show user
Show order
Show payment












```

`useModalContext` also has a component version. If you prefer using components, you can give it a try as well.

```vue

import { ModalContext, ModalProvider } from "vue-use-modal-context"



Show user
Show order
Show payment













```

## Tutorial - global context
You might need a global modal context that spans across components and contexts. In such cases, you can use `useGlobalModalContext`.

To use global modal, you need register plugin. Please refer to [document](#install).

### setup global modal
You can set ` anywhere. Remember to set it as `global`.

It is recommended to use it in the top-level component (e.g., `App.vue`):

```vue



```

Then, you can use `useGlobalModalContext` anywhere.

```vue

import { useGlobalModalContext } from "vue-use-modal-context"

const { openGlobalModal, patchGlobalModal, closeGlobalModal, } = useGlobalModalContext()

onMounted(() => {
openGlobalModal("LoginModal")
})

```

## documentation

### `useModalContext` and ``
`useModalContext` is a composition function. It uses the `provide` to pass modal context data to child components. Additionally, it returns three functions:

- `openModal(name: string, data?: Record) => void`: Opens the modal with the specified name and passes data. When passing data, it completely overwrites the existing data. Data is optional, but if provided, it must be an object. If not provided, the modal data will be the initial data.
- `closeModal(name: string) => void`: Closes the modal with the specified name.

- `patchModal(name: string, data: Record | (data) => Record) => void`:
- Updates the data of the specified modal.
- It's not an overwrite but rather an update in a way similar to `Object.assign`.
- It's recommended to perform patchModal after openModal.
- From `0.3.0`, data can be a update function, it receive a current modal data, and it return value will be merged to modal data.

```ts
// From 0.3.0
// patch modal by function data
patchModal("UserModal" ,(currentData) => {
return currentData.userId === 123 ? {
order: [
...currentData.order,
newOrder
]
} : {}
})
```

#### ``
`` is the component version of `useModalContext`, and it is a renderless component. These three functions can also be obtained in the `scoped slot` of the `` component.

```html

```

You can use `ref` to access it methods from `setup`.

```vue

import { ref, onMounted } from 'vue'

const ModalContextRef = ref()
onMounted(() => {
if (ModalContextRef.value){
ModalContextRef.value.openModal('UserModal', { userId: 3310 })
// or closeModal, patchModal ....
}
})



```

### `useModalProvider` and ``
`` is the component version of `useModalProvider` and is a renderless component. It registers the modal within its own `ModalContext`.

It must be placed inside the `ModalContext`. In other words, its parent component or a higher-level component must have either `useModalContext` or ``.

`` provides the following parameters:

- `name`: Required. Sets the name of the modal, corresponding to the first argument of openModal.
- `init-data`: Optional. Determines the initial state of `modal.data`. If not provided, it defaults to `{}`.
- `global`: `boolean`. Specifies whether it belongs to the globalModalContext. The default is `false` (see [globalModalContext](#useglobalmodalcontext-useglobalmodal)).
`reset-after-close`: `boolean`. Determines whether to reset data back to `init-data` after closing. The default is `false`.

`` provides the following `scoped slot`:

- `modal`: Contains the state of the modal and some functions. It is a `reactive` object, so **do not destructure this object**.

- `modal.show`: boolean, indicating whether the modal is open or closed.
- `modal.data`: Defaults to `{}`, and if `init-data` is provided, it defaults to `init-data`. When calling `openModal`, if data is passed, `modal.data` becomes that data. You can also modify `modal.data` when calling `patchModal`.
- `closeAnd(fn: () => any)`: Closes the modal and executes `fn`. Useful when setting event handlers.

Here's an example of using `closeAnd`:

```html



```

### `useModalProvider`
`useModalProvider` is a composition function。`` use `useModalProvider` internally.

params:`(name: string, initData: Record = {}, resetAfterClose: boolean = false, global: boolean = false)`

- `name`: Required. Sets the name of the modal, corresponding to the first argument of `openModal`.
- `initData`: Optional. Determines the initial state of `modal.data`. If not provided, it defaults to `{}`.
- `resetAfterClose`: `Optional`. Specifies whether to reset data back to `initData` after closing. The default is `false`.
- `global`: `boolean`. Specifies whether it belongs to the globalModalContext. The default is false (see [globalModalContext](#useglobalmodalcontext-useglobalmodal)).

Returns:
`modal`: Same as the modal in the scoped slot.

### `useGlobalModalContext`
`useGlobalModalContext` works the same as `useModalContext`, but manipulate global context. it will returns:

- `openGlobalModal`: Similar to openModal, but can only open global modals.
- `closeGlobalModal`: Similar to closeModal, but can only close global modals.
- `patchGlobalModal`: Similar to patchModal, but can only patch global modals.

### Types
Most types in this package are exposed. The following explains the most commonly used type settings.

#### Global components type
When you are using globally registered components (e.g: plugin), if you are using `vscode + volar`, you can set the global components type through the following way:

```ts
// src/components.d.ts
import { ModalContext, ModalProvider } from 'vue-use-modal-context'

declare module 'vue' {
export interface GlobalComponents {
ModalContext: typeof ModalContext
ModalProvider: typeof ModalProvider
}
}
```