{"id":13441961,"url":"https://github.com/f/vue-wait","last_synced_at":"2025-05-14T14:08:00.402Z","repository":{"id":32537162,"uuid":"96582583","full_name":"f/vue-wait","owner":"f","description":"Complex Loader and Progress Management for Vue/Vuex and Nuxt Applications","archived":false,"fork":false,"pushed_at":"2022-12-10T16:57:01.000Z","size":6999,"stargazers_count":1999,"open_issues_count":44,"forks_count":100,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-04-11T06:14:12.915Z","etag":null,"topics":["activity-indicator","loader","loader-component","loaders","loading","nuxt-module","progress","progress-bar","spinner","vue","vue-components","vue-progress","vuex","vuex-store"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/f.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"patreon":"fka"}},"created_at":"2017-07-07T23:03:42.000Z","updated_at":"2025-03-23T22:04:51.000Z","dependencies_parsed_at":"2023-01-14T21:31:44.287Z","dependency_job_id":null,"html_url":"https://github.com/f/vue-wait","commit_stats":null,"previous_names":["f/vuex-loading"],"tags_count":56,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f%2Fvue-wait","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f%2Fvue-wait/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f%2Fvue-wait/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f%2Fvue-wait/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/f","download_url":"https://codeload.github.com/f/vue-wait/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254159512,"owners_count":22024562,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activity-indicator","loader","loader-component","loaders","loading","nuxt-module","progress","progress-bar","spinner","vue","vue-components","vue-progress","vuex","vuex-store"],"created_at":"2024-07-31T03:01:40.109Z","updated_at":"2025-05-14T14:08:00.384Z","avatar_url":"https://github.com/f.png","language":"JavaScript","readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"./resources/logo.png\" width=\"500\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n Multiple Process Loader Management for \u003ca href=\"http://vuejs.org/\" rel=\"nofollow\" class=\"rich-diff-level-one\"\u003eVue\u003c/a\u003e and (optionally) \u003ca href=\"http://vuex.vuejs.org/\" rel=\"nofollow\" class=\"rich-diff-level-one\"\u003eVuex\u003c/a\u003e.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n \u003cstrong class=\"rich-diff-level-one\"\u003eRead the \u003ca href=\"https://medium.com/@fkadev/managing-complex-waiting-experiences-on-web-uis-29534d2d92a8\" rel=\"nofollow\"\u003eMedium post \"Managing Complex Waiting Experiences on Web UIs\"\u003c/a\u003e.\u003c/strong\u003e\n\u003c/p\u003e\n\n[![npm version](https://badge.fury.io/js/vue-wait.svg)](https://badge.fury.io/js/vue-wait)\n\n---\n\n![vue-wait](https://user-images.githubusercontent.com/196477/42170484-4d91e36a-7e1f-11e8-9cee-816bfe857db2.gif)\n\n\u003e [Play with demo above](https://f.github.io/vue-wait/).\n\n**vue-wait** helps to manage multiple loading states on the page without any conflict. It's based on a **very simple idea** that manages an array (or Vuex store optionally) with multiple loading states. The **built-in loader component** listens its registered loader and immediately become loading state.\n\n# ⏩Quick Start\n\nIf you are a **try and learn** developer, you can start trying the **vue-wait** now using [codesandbox.io](https://codesandbox.io).\n\n[![Edit VueWait Sandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/85q3vpm42?autoresize=1\u0026hidenavigation=1\u0026module=%2Fsrc%2Fcomponents%2FMyList.vue)\n\n### 1. Install:\n```bash\nyarn add vue-wait\n```\n\n### 2. Require:\n#### For Vue 2.x\n```js\nimport VueWait from 'vue-wait'\n\nVue.use(VueWait)\n\nnew Vue({\n  // your vue config\n  wait: new VueWait(),\n})\n```\n\n#### For Vue 3.x\n```js\nimport { createApp } from 'vue'\nimport { createVueWait } from 'vue-wait'\nimport App from './App.vue'\n\nconst VueWait = createVueWait()\n\ncreateApp(App)    // Create app with root component\n  .use(VueWait)   // Register vue-wait\n  .mount('#app')\n```\n\n### 3. Use in Your Components\n\n```vue\n\u003ctemplate\u003e\n  \u003cv-wait for=\"my list is to load\"\u003e\n    \u003ctemplate slot=\"waiting\"\u003e\n      \u003cdiv\u003e\n        \u003cimg src=\"loading.gif\" /\u003e\n        Loading the list...\n      \u003c/div\u003e\n    \u003c/template\u003e\n    \u003cul\u003e\n      \u003cli v-for=\"item in myList\"\u003e{{ item }}\u003c/li\u003e\n    \u003c/ul\u003e\n  \u003c/v-wait\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\n  export default {\n    data() {\n      return {\n        myList: []\n      }\n    },\n    async created() {\n      // start waiting\n      this.$wait.start('my list is to load');\n\n      this.myList = await fetch('/my-list-url');\n\n      // stop waiting\n      this.$wait.end('my list is to load');\n    },\n  };\n\u003c/script\u003e\n```\n\n\u003e **vue-wait has more abilities to make the management easier, please read the complete documentation.**\n\n# ▶️Detailed Start\n\n## 📦  Requirements\n\n- [Vue.js](https://vuejs.org) (v2.0.0+)\n\n## 🚀  Power Supplies\n- [Vuex](http://vuex.vuejs.org), optionally (v2.0.0+)\n\n## 🔧 Installation\n\nvia CLI:\n\n```bash\n$ yarn add vue-wait\n# or if you using npm\n$ npm install vue-wait\n```\n\nvia Vue UI:\n\n\u003cimg src=\"./resources/vue-ui-install.png\" width=\"600\" /\u003e\n\n## 📖 Usage\n\n```js\nimport VueWait from 'vue-wait'\n\nVue.use(VueWait) // add VueWait as Vue plugin\n```\n\nThen you should register `wait` property (`VueWait` instance) to the Vue instance:\n\n```js\nnew Vue({\n  el: '#app',\n  store,\n  wait: new VueWait({\n    // Defaults values are following:\n    useVuex: false,              // Uses Vuex to manage wait state\n    vuexModuleName: 'wait',      // Vuex module name\n\n    registerComponent: true,     // Registers `v-wait` component\n    componentName: 'v-wait',     // \u003cv-wait\u003e component name, you can set `my-loader` etc.\n\n    registerDirective: true,     // Registers `v-wait` directive\n    directiveName: 'wait',       // \u003cspan v-wait /\u003e directive name, you can set `my-loader` etc.\n\n  }),\n});\n```\n\n## ♻️ Usage with Vuex\n\nSimply set `useVuex` parameter to `true` and optionally override\n`vuexModuleName`\n\n```js\nimport VueWait from 'vue-wait'\n\nVue.use(Vuex)\nVue.use(VueWait) // add VueWait as Vue plugin\n```\n\nThen you should register `VueWait` module:\n\n```js\nnew Vue({\n  el: '#app',\n  store,\n  wait: new VueWait({\n    useVuex: true, // You must pass this option `true` to use Vuex\n    vuexModuleName: 'vuex-example-module' // It's optional, `wait` by default.\n  }),\n});\n```\n\nNow `VueWait` will use `Vuex` store for data management which can be traced in `Vue DevTools \u003e Vuex`\n\n## ♻️ Usage with Nuxt.js\n\nAdd `vue-wait/nuxt` to modules section of `nuxt.config.js`\n\n```js\n{\n  modules: [\n    // Simple usage\n    'vue-wait/nuxt'\n\n    // Optionally passing options in module configuration\n    ['vue-wait/nuxt', { useVuex: true }]\n  ],\n\n  // Optionally passing options in module top level configuration\n  wait: { useVuex: true }\n}\n```\n\n## 🔁 `VueWait` Options\n\nYou can use this options for customize VueWait behavior.\n\n| Option Name | Type | Default | Description |\n| ----------- | ---- | ------- | ----------- |\n| `accessorName` | `String` | `\"$wait\"` | You can change this value to rename the accessor. E.g. if you rename this to `$w`, your `VueWait` methods will be accessible by `$w.waits(..)` etc. |\n| `useVuex` | `Boolean` | `false` | Use this value for enabling integration with `Vuex` store. When this value is true `VueWait` will store data in `Vuex` store and all changes to this data will be made by dispatching actions to store |\n| `vuexModuleName` | `String` | `\"wait\"` | Name for `Vuex` store if `useVuex` set to true, otherwise not used. |\n| `registerComponent` | `Boolean` | `true` | Registers `v-wait` component. |\n| `componentName` | `String` | `\"v-wait\"` | Changes `v-wait` component name. |\n| `registerDirective` | `Boolean` | `true` | Registers `v-wait` directive. |\n| `directiveName` | `String` | `\"v-wait\"` | Changes `v-wait` directive name. |\n\n## 🌈 Global Template Helpers\n\n**vue-wait** provides some helpers to you to use in your templates.\nAll features can be obtained from $wait property in Vue components.\n\n#### `.any`\n\nReturns boolean value if any loader exists in page.\n\n```vue\n\u003ctemplate\u003e\n  \u003cprogress-bar v-if=\"$wait.any\"\u003ePlease wait...\u003c/progress-bar\u003e\n\u003c/template\u003e\n```\n\n#### `.is(loader String | Matcher)` or `.waiting(loader String | Matcher)`\n\nReturns boolean value if given loader exists in page.\n\n```vue\n\u003ctemplate\u003e\n  \u003cprogress-bar v-if=\"$wait.is('creating user')\"\u003eCreating User...\u003c/progress-bar\u003e\n\u003c/template\u003e\n```\n\nYou can use **`waiting`** alias instead of **`is`**.\n\n```vue\n\u003ctemplate\u003e\n  \u003cdiv v-if=\"$wait.waiting('fetching users')\"\u003e\n    Fetching users...\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\nAlso you can use matcher to make it more flexible:\n\nPlease see [matcher](https://github.com/sindresorhus/matcher/) library to see how to use matchers.\n\n```vue\n\u003ctemplate\u003e\n  \u003cprogress-bar v-if=\"$wait.is('creating.*')\"\u003eCreating something...\u003c/progress-bar\u003e\n\u003c/template\u003e\n```\n\n#### `.is(loaders Array\u003cString | Matcher\u003e)` or `.waiting(loaders Array\u003cString | Matcher\u003e)`\n\nReturns boolean value if some of given loaders exists in page.\n\n```vue\n\u003ctemplate\u003e\n  \u003cprogress-bar v-if=\"$wait.is(['creating user', 'page loading'])\"\u003eCreating User...\u003c/progress-bar\u003e\n\u003c/template\u003e\n```\n\n#### `.start(loader String)`\n\nStarts the given loader.\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton @click=\"$wait.start('creating user')\"\u003eCreate User\u003c/button\u003e\n\u003c/template\u003e\n```\n\n#### `.end(loader String)`\n\nStops the given loader.\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton @click=\"$wait.end('creating user')\"\u003eCancel\u003c/button\u003e\n\u003c/template\u003e\n```\n\n#### `.progress(loader String, current [, total = 100])`\n\nSets the progress of the given loader.\n\n```vue\n\u003ctemplate\u003e\n  \u003cprogress min=\"0\" max=\"100\" :value=\"$wait.percent('downloading')\" /\u003e\n  \u003cbutton @click=\"$wait.progress('downloading', 10)\"\u003eSet progress to 10\u003c/button\u003e\n  \u003cbutton @click=\"$wait.progress('downloading', 50)\"\u003eSet progress to 50\u003c/button\u003e\n  \u003cbutton @click=\"$wait.progress('downloading', 50, 200)\"\u003eSet progress to 50 of 200 (25%)\u003c/button\u003e\n\u003c/template\u003e\n```\n\n##### Completing the Progress\n\nTo complete the progress, `current` value should be set bigger than `100`.\nIf you `total` is given, `current` must be bigger than `total`.\n\n```vue\n\u003cbutton @click=\"$wait.progress('downloading', 101)\"\u003eSet as downloaded (101 of 100)\u003c/button\u003e\n```\n\nor\n\n```vue\n\u003cbutton @click=\"$wait.progress('downloading', 5, 6)\"\u003eSet as downloaded (6 of 5)\u003c/button\u003e\n```\n\n#### `.percent(loader String)`\n\nReturns the percentage of the given loader.\n\n```vue\n\u003ctemplate\u003e\n  \u003cprogress min=\"0\" max=\"100\" :value=\"$wait.percent('downloading')\" /\u003e\n\u003c/template\u003e\n```\n\n## 🏹 Directives\n\nYou can use directives to make your template cleaner.\n\n#### `v-wait:visible='\"loader name\"'`\n\nShows if the given loader is loading.\n\n```vue\n\u003ctemplate\u003e\n  \u003cprogress-bar v-wait:visible='\"creating user\"'\u003eCreating User...\u003c/progress-bar\u003e\n\u003c/template\u003e\n```\n\n#### `v-wait:hidden='\"loader name\"'` or `v-wait:visible.not='\"loader name\"'`\n\nHides if the given loader is loading.\n\n```vue\n\u003ctemplate\u003e\n  \u003cmain v-wait:hidden='\"creating *\"'\u003eSome Content\u003c/main\u003e\n\u003c/template\u003e\n```\n\n#### `v-wait:disabled='\"loader name\"'`\n\nSets `disabled=\"disabled\"` attribute to element if the given loader is loading.\n\n```vue\n\u003ctemplate\u003e\n  \u003cinput v-wait:disabled=\"'*'\" placeholder=\"Username\" /\u003e\n  \u003cinput v-wait:disabled=\"'*'\" placeholder=\"Password\" /\u003e\n\u003c/template\u003e\n```\n\n#### `v-wait:enabled='\"loader name\"'` or `v-wait:disabled.not='\"loader name\"'`\n\nRemoves `disabled=\"disabled\"` attribute to element if the given loader is loading.\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton v-wait:enabled='\"creating user\"'\u003eAbort Request\u003c/button\u003e\n\u003c/template\u003e\n```\n\n#### `v-wait:click.start='\"loader name\"'`\n\nStarts given loader on click.\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton v-wait:click.start='\"create user\"'\u003eStart loader\u003c/button\u003e\n\u003c/template\u003e\n```\n\n#### `v-wait:click.end='\"loader name\"'`\n\nEnds given loader on click.\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton v-wait:click.end='\"create user\"'\u003eEnd loader\u003c/button\u003e\n\u003c/template\u003e\n```\n\n#### `v-wait:toggle='\"loader name\"'`\n\nToggles given loader on click.\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton v-wait:toggle='\"flip flop\"'\u003eToggles the loader\u003c/button\u003e\n\u003c/template\u003e\n```\n\n#### `v-wait:click.progress='[\"loader name\", 80]'`\n\nSets the progress of given loader on click.\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton v-wait:click.progress='[\"downloading\", 80]'\u003eSet the \"downloading\" loader to 80\u003c/button\u003e\n\u003c/template\u003e\n```\n\n## 🔌 Loading Action and Getter Mappers\n\n**vue-wait** provides `mapWaitingActions` and `mapWaitingGetters` mapper to be used with your Vuex stores.\n\nLet's assume you have a store and async **action**s called `createUser` and `updateUser`.\nIt will call the methods you map and will start loaders while action is resolved.\n\n```js\nimport { mapWaitingActions, mapWaitingGetters } from 'vue-wait'\n\n// ...\n  methods: {\n    ...mapWaitingActions('users', {\n      getUsers: 'loading users',\n      createUser: 'creating user',\n      updateUser: 'updating user',\n    }),\n  },\n  computed: {\n    ...mapWaitingGetters({\n      somethingWithUsers: [\n        'loading users',\n        'creating user',\n        'updating user',\n      ],\n      deletingUser: 'deleting user',\n    }),\n  }\n// ...\n```\n\nYou can also map **action** to custom method and customize loader name like in example below:\n\n```js\nimport { mapWaitingActions, mapWaitingGetters } from 'vue-wait'\n\n// ...\n  methods: {\n    ...mapWaitingActions('users', {\n      getUsers: { action: 'getUsers', loader: 'loading users' },\n      createUser: { action: 'createUser', loader: 'creating user'},\n      createSuperUser: { action: 'createUser', loader: 'creating super user' },\n    }),\n  },\n// ...\n```\n\nThere is also possibility to use array as a second argument to mapWaitingActions:\n```js\n// ...\n  methods: {\n    ...mapWaitingActions('users', [\n      'getUsers',\n      { method: 'createUser', action: 'createUser', loader: 'creating user'},\n      { method: 'createSuperUser', action: 'createUser', loader: 'creating super user' },\n    ]),\n  },\n// ...\n\n\n```\n\n### ☢️Advanced Getters and Actions Usage\n\n\u003e The Vuex module name is `wait` by default. If you've changed on config, you should get it by `rootGetters['\u003cvuex module name\u003e/is']` or `rootGetters['\u003cvuex module name\u003e/any']`.\n\nYou can access `vue-wait`'s Vuex getters using `rootGetters` in Vuex.\n\n```js\ngetters: {\n  cartOperationInProgress(state, getters, rootState, rootGetters) {\n    return rootGetters['wait/is']('cart.*');\n  }\n},\n```\n\nAnd you can start and end loaders using `wait` actions. You must pass `root: true` option to the `dispatch` method.\n\n```js\nactions: {\n  async addItemToCart({ dispatch }, item) {\n    dispatch('wait/start', 'cart.addItem', { root: true });\n    await CartService.addItem(item);\n    dispatch('wait/end', 'cart.addItem', { root: true });\n  }\n},\n```\n\n#### `waitFor(loader String, func Function [,forceSync = false])`\n\nDecorator that wraps function, will trigger a loading and will end loader after the original function (`func` argument) is finished.\n\nBy default `waitFor` return async function, if you want to wrap default sync function pass `true` in last argument\n\n_Example using with async function_\n\n```js\nimport { waitFor } from 'vue-wait';\n\n...\nmethods: {\n  fetchDataFromApi: waitFor('fetch data', async function () {\n    function sleep(ms) {\n      return new Promise(resolve =\u003e setTimeout(resolve, ms));\n    }\n    // do work here\n    await sleep(3000);\n    // simulate some api call\n    this.fetchResponse = Math.random()\n  })\n}\n...\n```\n\nSee also `examples/wrap-example`\n\n## 💧 Using `v-wait` Component\n\nIf you disable `registerComponent` option then import and add `v-wait` into components\n\n```js\nimport vLoading from 'vue-wait/src/components/v-wait.vue'\ncomponents: {\n  'v-wait': vLoading\n}\n```\n\nIn template, you should wrap your content with `v-wait` component to show loading on it.\n\n```vue\n\u003cv-wait for='fetching data'\u003e\n  \u003ctemplate slot='waiting'\u003e\n    This will be shown when \"fetching data\" loader starts.\n  \u003c/template\u003e\n\n  This will be shown when \"fetching data\" loader ends.\n\u003c/v-wait\u003e\n```\n\nBetter example for a `button` with loading state:\n\n```vue\n\u003cbutton :disabled='$wait.is(\"creating user\")'\u003e\n  \u003cv-wait for='creating user'\u003e\n    \u003ctemplate slot='waiting'\u003eCreating User...\u003c/template\u003e\n    Create User\n  \u003c/v-wait\u003e\n\u003c/button\u003e\n```\n\n## 🔁 Transitions\n\nYou can use transitions with `v-wait` component.\n\nJust pass `\u003ctransition\u003e` props and listeners to the `v-wait` with `transition` prop.\n\n```vue\n\u003cv-wait for=\"users\"\n  transition=\"fade\"\n  mode=\"out-in\"\n  :duration=\"1000\"\n  enter-active-class=\"enter-active\"\n  @leave='someAwesomeFinish()'\n  \u003e\n  \u003ctemplate slot=\"waiting\"\u003e\n    \u003cp\u003eLoading...\u003c/p\u003e\n  \u003c/template\u003e\n  My content\n\u003c/v-wait\u003e\n```\n\n## ⚡️ Making Reusable Loader Components\n\nWith reusable loader components, you will be able to use custom loader components as example below. This will allow you to create better **user loading experience**.\n\n\u003cimg src=\"./resources/vue-wait-2.gif\" width=\"480\"\u003e\n\nIn this example above, the **tab gets data from back-end**, and the **table loads data from back-end at the same time**. With **vue-wait**, you will be able to manage these two seperated loading processes easily:\n\n```vue\n\u003ctemplate lang='pug'\u003e\n  \u003cdiv\u003e\n    \u003cv-wait for=\"fetching tabs\"\u003e\n      \u003ctemplate slot=\"waiting\"\u003e\n        \u003cb-tabs\u003e\n          \u003ctemplate slot=\"tabs\"\u003e\n            \u003cb-nav-item active=\"active\" disabled\u003e\n              \u003cv-icon name=\"circle-o-notch\" spin=\"spin\" /\u003e\n            \u003c/b-nav-item\u003e\n          \u003c/template\u003e\n        \u003c/b-tabs\u003e\n      \u003c/template\u003e\n      \u003cb-tabs\u003e\n        \u003ctemplate slot=\"tabs\"\u003e\n          \u003cb-nav-item v-for=\"tab in tabs\"\u003e{{ tab.name }}\u003c/b-nav-item\u003e\n        \u003c/template\u003e\n      \u003c/b-tabs\u003e\n    \u003c/v-wait\u003e\n    \u003cv-wait for=\"fetching data\"\u003e\n      \u003ctable-gradient-spinner slot=\"waiting\" /\u003e\n      \u003ctable\u003e\n        \u003ctr v-for=\"row in data\"\u003e\n          \u003c!-- ...--\u003e\n        \u003c/tr\u003e\n      \u003c/table\u003e\n    \u003c/v-wait\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n```\n\nYou may want to design your own reusable loader for your project. You better create a wrapper component called `my-waiter`:\n\n```vue\n\u003c!-- MySpinner.vue --\u003e\n\u003ci18n\u003e\n  tr:\n    loading: Yükleniyor...\n  en:\n    loading: Loading...\n\u003c/i18n\u003e\n\n\u003ctemplate\u003e\n  \u003cdiv class=\"loading-spinner\"\u003e\n    \u003cv-icon name=\"refresh\" spin=\"spin\" /\u003e\n    \u003cspan\u003e{{ $t('loading') }}\u003c/span\u003e\n  \u003c/div\u003e\n\u003c/template\u003e\n\n\u003cstyle scoped lang=\"scss\"\u003e\n  .loading-spinner {\n    opacity: 0.5;\n    margin: 50px auto;\n    text-align: center;\n    .fa-icon {\n      vertical-align: middle;\n      margin-right: 10px;\n    }\n  }\n\u003c/style\u003e\n```\n\nNow you can use your spinner everywhere using `slot='waiting'` attribute:\n\n```vue\n\u003ctemplate lang=\"pug\"\u003e\n  \u003cv-wait for=\"fetching data\"\u003e\n    \u003cmy-waiter slot=\"waiting\" /\u003e\n    \u003cdiv\u003e\n      \u003cp\u003eMy main content after fetching data...\u003c/p\u003e\n    \u003c/div\u003e\n  \u003c/v-wait\u003e\n\u003c/template\u003e\n```\n\n## 📦 Using with external spinner libraries\n\nYou can use `vue-wait` with another spinner libraries like [epic-spinners](https://github.com/epicmaxco/epic-spinners) or other libraries. You just need to add `slot=\"waiting\"` to the component and Vue handles rest of the work.\n\nFirst register the component,\n```js\nimport { OrbitSpinner } from 'epic-spinners';\nVue.component('orbit-spinner', OrbitSpinner);\n```\n\nThen use it in your as a `v-wait`'s `waiting` slot.\n```vue\n\u003cv-wait for='something to load'\u003e\n  \u003corbit-spinner\n    slot='waiting'\n    :animation-duration=\"1500\"\n    :size=\"64\"\n    :color=\"'#ff1d5e'\"\n  /\u003e\n\u003c/v-wait\u003e\n```\n\n... and done!\n\nFor other libraries you can use, please see [Loaders section of **vuejs/awesome-vue**](https://github.com/vuejs/awesome-vue#loader).\n\n## 🚌 Run example\n\nUse `npm run dev-vuex`, `npm run dev-vue` or `npm run dev-wrap` commands.\nfor running examples locally.\n\n## ✔ Testing components\n\nYou can test components using `vue-wait` but it requires configuration. Let's take a basic component for instance:\n\n```vue\n\u003cv-wait for=\"loading\"\u003e\n   \u003cSpinner slot=\"waiting\" /\u003e\n   \u003cul class=\"suggestions\"\u003e\n      \u003cli v-for=\"suggestion in suggestions\"\u003e{{ suggestion.Name }}\u003c/li\u003e\n   \u003c/ul\u003e\n\u003c/v-wait\u003e\n```\n\n```js\nconst localVue = createLocalVue();\nlocalVue.use(Vuex); // optionally when you use Vuex integration\n\nit('uses vue-wait component', () =\u003e {\n    const wrapper = shallowMount(Suggestions, { localVue });\n    expect(wrapper.find('.suggestions').exists()).toBe(true);\n});\n```\n\n`vue-test-utils` will replace `v-wait` component with an empty `div`, making it difficult to test correctly.\n\nFirst, make your local Vue instance use `vue-wait`,\n\n```js\nconst localVue = createLocalVue();\nlocalVue.use(Vuex); // optionally when you use Vuex integration\nlocalVue.use(VueWait);\n```\n\nThen inject the `wait` property using `VueWait` constructor,\n\n```js\nit('uses vue-wait component', () =\u003e {\n    const wrapper = shallowMount(SuggestedAddresses, {\n      localVue,\n      wait: new VueWait()\n    });\n    expect(wrapper.find('.suggestions').exists()).toBe(true); // it works!\n});\n```\n\n## For Development on vue-wait\nInstall packages\n```bash\n$ yarn install\n# or if you using npm\n$ npm install\n```\n\nBundle it\n```bash\n$ yarn bundle\n# or if you using npm\n$ npm run bundle\n```\n\n## 🎯 Contributors\n\n - Fatih Kadir Akın, (creator)\n - Igor, (maintainer, made Vuex-free)\n\n## 🔗 Other Implementations\n\nSince **vue-wait** based on a very simple idea, it can be implemented on other frameworks.\n\n - [react-wait](https://github.com/f/react-wait): Multiple Process Loader Management for React.\n - [dom-wait](https://github.com/f/dom-wait): Multiple Process Loader Management for vanilla JavaScript.\n\n## 🔑 License\n\nMIT © [Fatih Kadir Akın](https://github.com/f)\n","funding_links":["https://patreon.com/fka"],"categories":["HarmonyOS","JavaScript","UI组件","Components \u0026 Libraries","UI Components","UI Components [🔝](#readme)"],"sub_categories":["Windows Manager","装载机","UI Components","Loader"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff%2Fvue-wait","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ff%2Fvue-wait","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff%2Fvue-wait/lists"}