Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composition API #75

Merged
merged 2 commits into from
Apr 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Wanna try it out? Check out the [live demo](https://maronato.github.io/vue-toast
- [Plugin registration](#plugin-registration)
- [Nuxt registration](#nuxt-registration)
- [Injecting the Toast CSS](#injecting-the-toast-css)
- [Composition API registration](#composition-api-registration)
- [Generic registration](#generic-registration)
- [Positioning the Toast](#positioning-the-toast)
- [Toast types](#toast-types)
- [Setting the toast timeout](#setting-the-toast-timeout)
Expand Down Expand Up @@ -72,6 +74,8 @@ Wanna try it out? Check out the [live demo](https://maronato.github.io/vue-toast
## Features

- Built-in Nuxt support
- Support for the new [Composition API](https://composition-api.vuejs.org/api.html) and Vue 3
- Generic registration allows it to be used inside any app, even React!
- Fully written in Typescript with full types support
- RTL support
- Easy to set up for real, you can make it work in less than 10sec!
Expand Down Expand Up @@ -221,6 +225,69 @@ export default {

If your CSS file is actually an SCSS or SASS file, just make sure that you have the correct loaders installed. See [Nuxt docs](https://nuxtjs.org/api/configuration-css) on that.

### Composition API registration
Vue Toastification comes with built-in support for the Composition API through the [@vue/composition-api](https://github.com/vuejs/composition-api) package. It is fully optional and won't interfere with your usage if you do not use composition.

Composable plugins are a little different than regular Vue plugins as they rely on providers and injectors to work without access to the `this` keyword. Vue Toastification exposes two new functions to make that possible: `provideToast` and `useToast`.

To access toasts inside `setup`, you first need to register the provider. To make the toasts available from anywhere within your application, set up the provider on the root component of your app:
```js
// App.vue

// Import from vue-toastification/composition, not vue-toastification
import { provideToast } from "vue-toastification/composition";

// Then, on the setup method
setup() {
// Pass the Plugin Options here
provideToast({ timeout: 3000 });
}
```
This is similar to `Vue.use(Toast)`, but will **not** register `$toast` to the Vue instance.

Then get access to the `toast` interface on your components with `useToast`:
```js
// MyComponent.vue

import { useToast } from "vue-toastification/composition";
// ...

setup() {
// Same interface as this.$toast
const toast = useToast();

const showToast = () => toast.success("I'm a toast!");
const clearToasts = () => toast.clear();
return { showToast, clearToasts };
}
```

> **Note**: Registering Vue Toastification with `provideToast` does **not** register it as a regular Vue Plugin, so you will **not** have access to it from `this.$toast`. Also, do not register with both `provideToast` and `Vue.use` at the same time, as that will register it twice leading to unpredictable behavior.

### Generic registration
Vue Toastification allows you to register it as a generic interface not bound to Vue as a plugin. That may be useful if you are using it on an app that does not use Vue.

It still depends on Vue as a framework, but not on the root vue instance of your page.

To register it, use the `createToastInterface` helper:
```js
import { createToastInterface } from "vue-toastification";

const pluginOptions = {
timeout: 4000
};

// Create the interface
const toast = createToastInterface(pluginOptions);

// Use it
toast.success("Standalone toasts!");
```

When calling `createToastInterface`, it will automatically mount the toast container as you would expect. It returns the `toast` interface and you can use it as you would with `this.$toast`.

`createToastInterface` may take a second, optional, `Vue` instance parameter. Use it to specify an optional parent Vue instance to the interface.

### Positioning the Toast

By default, the toasts will be displayed at the top right corner of your screen, but you can set it manually using the `position` option.
Expand Down
5 changes: 5 additions & 0 deletions composition/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { PluginOptions } from "vue-toastification/dist/types/src/types";
import ToastInterface from "vue-toastification/dist/types/src/ts/interface";
declare let provideToast: (options?: PluginOptions) => void;
declare let useToast: () => ReturnType<typeof ToastInterface>;
export { provideToast, useToast };
14 changes: 14 additions & 0 deletions composition/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { inject, provide } from "@vue/composition-api";
import { createToastInterface } from "vue-toastification";

const toastSymbol = Symbol("Vue Toastification");

/** @type {ReturnType<typeof createToastInterface>} */
const injectDefault = {};

// Generate provider and consumer
const provideToast = options =>
provide(toastSymbol, createToastInterface(options));
const useToast = () => inject(toastSymbol, injectDefault);

export { provideToast, useToast };
3 changes: 3 additions & 0 deletions examples/vue-composition-api-typescript/.browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead
20 changes: 20 additions & 0 deletions examples/vue-composition-api-typescript/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
root: true,
env: {
node: true
},
extends: [
"plugin:vue/essential",
"eslint:recommended",
"@vue/typescript/recommended",
"@vue/prettier",
"@vue/prettier/@typescript-eslint"
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off"
}
};
21 changes: 21 additions & 0 deletions examples/vue-composition-api-typescript/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
24 changes: 24 additions & 0 deletions examples/vue-composition-api-typescript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# vue-composition-api-typescript

## Project setup
```
yarn install
```

### Compiles and hot-reloads for development
```
yarn serve
```

### Compiles and minifies for production
```
yarn build
```

### Lints and fixes files
```
yarn lint
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
3 changes: 3 additions & 0 deletions examples/vue-composition-api-typescript/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"]
};
44 changes: 44 additions & 0 deletions examples/vue-composition-api-typescript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "vue-composition-api-typescript",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@vue/composition-api": "^0.5.0",
"core-js": "^3.6.4",
"vue": "^2.6.11",
"vue-toastification": "^1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0",
"@vue/cli-plugin-babel": "~4.3.0",
"@vue/cli-plugin-eslint": "~4.3.0",
"@vue/cli-plugin-typescript": "~4.3.0",
"@vue/cli-service": "~4.3.0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-vue": "^6.2.2",
"lint-staged": "^9.5.0",
"prettier": "^1.19.1",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"typescript": "~3.8.3",
"vue-template-compiler": "^2.6.11"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"vue-cli-service lint",
"git add"
]
}
}
Binary file not shown.
17 changes: 17 additions & 0 deletions examples/vue-composition-api-typescript/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
38 changes: 38 additions & 0 deletions examples/vue-composition-api-typescript/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld
msg="Welcome to the Vue Toastification + Typescript + Composition API example"
/>
</div>
</template>

<script lang="ts">
import { defineComponent } from "@vue/composition-api";

import { provideToast } from "vue-toastification/composition";
import "vue-toastification/dist/index.css";

import HelloWorld from "./components/HelloWorld.vue";

export default defineComponent({
name: "App",
components: {
HelloWorld
},
setup() {
provideToast({ maxToasts: 5 });
}
});
</script>

<style lang="scss">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.