GithubHelp home page GithubHelp logo

f / vue-wait Goto Github PK

View Code? Open in Web Editor NEW
2.0K 20.0 107.0 6.83 MB

Complex Loader and Progress Management for Vue/Vuex and Nuxt Applications

License: MIT License

JavaScript 88.37% Vue 11.63%
vue vuex loading loader loaders activity-indicator vuex-store nuxt-module vue-components progress

vue-wait's Introduction

Multiple Process Loader Management for Vue and (optionally) Vuex.

Read the Medium post "Managing Complex Waiting Experiences on Web UIs".

npm version


vue-wait

Play with demo above.

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.

⏩Quick Start

If you are a try and learn developer, you can start trying the vue-wait now using codesandbox.io.

Edit VueWait Sandbox

1. Install:

yarn add vue-wait

2. Require:

For Vue 2.x

import VueWait from 'vue-wait'

Vue.use(VueWait)

new Vue({
  // your vue config
  wait: new VueWait(),
})

For Vue 3.x

import { createApp } from 'vue'
import { createVueWait } from 'vue-wait'
import App from './App.vue'

const VueWait = createVueWait()

createApp(App)    // Create app with root component
  .use(VueWait)   // Register vue-wait
  .mount('#app')

3. Use in Your Components

<template>
  <v-wait for="my list is to load">
    <template slot="waiting">
      <div>
        <img src="loading.gif" />
        Loading the list...
      </div>
    </template>
    <ul>
      <li v-for="item in myList">{{ item }}</li>
    </ul>
  </v-wait>
</template>

<script>
  export default {
    data() {
      return {
        myList: []
      }
    },
    async created() {
      // start waiting
      this.$wait.start('my list is to load');

      this.myList = await fetch('/my-list-url');

      // stop waiting
      this.$wait.end('my list is to load');
    },
  };
</script>

vue-wait has more abilities to make the management easier, please read the complete documentation.

▶️Detailed Start

📦 Requirements

🚀 Power Supplies

  • Vuex, optionally (v2.0.0+)

🔧 Installation

via CLI:

$ yarn add vue-wait
# or if you using npm
$ npm install vue-wait

via Vue UI:

📖 Usage

import VueWait from 'vue-wait'

Vue.use(VueWait) // add VueWait as Vue plugin

Then you should register wait property (VueWait instance) to the Vue instance:

new Vue({
  el: '#app',
  store,
  wait: new VueWait({
    // Defaults values are following:
    useVuex: false,              // Uses Vuex to manage wait state
    vuexModuleName: 'wait',      // Vuex module name

    registerComponent: true,     // Registers `v-wait` component
    componentName: 'v-wait',     // <v-wait> component name, you can set `my-loader` etc.

    registerDirective: true,     // Registers `v-wait` directive
    directiveName: 'wait',       // <span v-wait /> directive name, you can set `my-loader` etc.

  }),
});

♻️ Usage with Vuex

Simply set useVuex parameter to true and optionally override vuexModuleName

import VueWait from 'vue-wait'

Vue.use(Vuex)
Vue.use(VueWait) // add VueWait as Vue plugin

Then you should register VueWait module:

new Vue({
  el: '#app',
  store,
  wait: new VueWait({
    useVuex: true, // You must pass this option `true` to use Vuex
    vuexModuleName: 'vuex-example-module' // It's optional, `wait` by default.
  }),
});

Now VueWait will use Vuex store for data management which can be traced in Vue DevTools > Vuex

♻️ Usage with Nuxt.js

Add vue-wait/nuxt to modules section of nuxt.config.js

{
  modules: [
    // Simple usage
    'vue-wait/nuxt'

    // Optionally passing options in module configuration
    ['vue-wait/nuxt', { useVuex: true }]
  ],

  // Optionally passing options in module top level configuration
  wait: { useVuex: true }
}

🔁 VueWait Options

You can use this options for customize VueWait behavior.

Option Name Type Default Description
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.
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
vuexModuleName String "wait" Name for Vuex store if useVuex set to true, otherwise not used.
registerComponent Boolean true Registers v-wait component.
componentName String "v-wait" Changes v-wait component name.
registerDirective Boolean true Registers v-wait directive.
directiveName String "v-wait" Changes v-wait directive name.

🌈 Global Template Helpers

vue-wait provides some helpers to you to use in your templates. All features can be obtained from $wait property in Vue components.

.any

Returns boolean value if any loader exists in page.

<template>
  <progress-bar v-if="$wait.any">Please wait...</progress-bar>
</template>

.is(loader String | Matcher) or .waiting(loader String | Matcher)

Returns boolean value if given loader exists in page.

<template>
  <progress-bar v-if="$wait.is('creating user')">Creating User...</progress-bar>
</template>

You can use waiting alias instead of is.

<template>
  <div v-if="$wait.waiting('fetching users')">
    Fetching users...
  </div>
</template>

Also you can use matcher to make it more flexible:

Please see matcher library to see how to use matchers.

<template>
  <progress-bar v-if="$wait.is('creating.*')">Creating something...</progress-bar>
</template>

.is(loaders Array<String | Matcher>) or .waiting(loaders Array<String | Matcher>)

Returns boolean value if some of given loaders exists in page.

<template>
  <progress-bar v-if="$wait.is(['creating user', 'page loading'])">Creating User...</progress-bar>
</template>

.start(loader String)

Starts the given loader.

<template>
  <button @click="$wait.start('creating user')">Create User</button>
</template>

.end(loader String)

Stops the given loader.

<template>
  <button @click="$wait.end('creating user')">Cancel</button>
</template>

.progress(loader String, current [, total = 100])

Sets the progress of the given loader.

<template>
  <progress min="0" max="100" :value="$wait.percent('downloading')" />
  <button @click="$wait.progress('downloading', 10)">Set progress to 10</button>
  <button @click="$wait.progress('downloading', 50)">Set progress to 50</button>
  <button @click="$wait.progress('downloading', 50, 200)">Set progress to 50 of 200 (25%)</button>
</template>
Completing the Progress

To complete the progress, current value should be set bigger than 100. If you total is given, current must be bigger than total.

<button @click="$wait.progress('downloading', 101)">Set as downloaded (101 of 100)</button>

or

<button @click="$wait.progress('downloading', 5, 6)">Set as downloaded (6 of 5)</button>

.percent(loader String)

Returns the percentage of the given loader.

<template>
  <progress min="0" max="100" :value="$wait.percent('downloading')" />
</template>

🏹 Directives

You can use directives to make your template cleaner.

v-wait:visible='"loader name"'

Shows if the given loader is loading.

<template>
  <progress-bar v-wait:visible='"creating user"'>Creating User...</progress-bar>
</template>

v-wait:hidden='"loader name"' or v-wait:visible.not='"loader name"'

Hides if the given loader is loading.

<template>
  <main v-wait:hidden='"creating *"'>Some Content</main>
</template>

v-wait:disabled='"loader name"'

Sets disabled="disabled" attribute to element if the given loader is loading.

<template>
  <input v-wait:disabled="'*'" placeholder="Username" />
  <input v-wait:disabled="'*'" placeholder="Password" />
</template>

v-wait:enabled='"loader name"' or v-wait:disabled.not='"loader name"'

Removes disabled="disabled" attribute to element if the given loader is loading.

<template>
  <button v-wait:enabled='"creating user"'>Abort Request</button>
</template>

v-wait:click.start='"loader name"'

Starts given loader on click.

<template>
  <button v-wait:click.start='"create user"'>Start loader</button>
</template>

v-wait:click.end='"loader name"'

Ends given loader on click.

<template>
  <button v-wait:click.end='"create user"'>End loader</button>
</template>

v-wait:toggle='"loader name"'

Toggles given loader on click.

<template>
  <button v-wait:toggle='"flip flop"'>Toggles the loader</button>
</template>

v-wait:click.progress='["loader name", 80]'

Sets the progress of given loader on click.

<template>
  <button v-wait:click.progress='["downloading", 80]'>Set the "downloading" loader to 80</button>
</template>

🔌 Loading Action and Getter Mappers

vue-wait provides mapWaitingActions and mapWaitingGetters mapper to be used with your Vuex stores.

Let's assume you have a store and async actions called createUser and updateUser. It will call the methods you map and will start loaders while action is resolved.

import { mapWaitingActions, mapWaitingGetters } from 'vue-wait'

// ...
  methods: {
    ...mapWaitingActions('users', {
      getUsers: 'loading users',
      createUser: 'creating user',
      updateUser: 'updating user',
    }),
  },
  computed: {
    ...mapWaitingGetters({
      somethingWithUsers: [
        'loading users',
        'creating user',
        'updating user',
      ],
      deletingUser: 'deleting user',
    }),
  }
// ...

You can also map action to custom method and customize loader name like in example below:

import { mapWaitingActions, mapWaitingGetters } from 'vue-wait'

// ...
  methods: {
    ...mapWaitingActions('users', {
      getUsers: { action: 'getUsers', loader: 'loading users' },
      createUser: { action: 'createUser', loader: 'creating user'},
      createSuperUser: { action: 'createUser', loader: 'creating super user' },
    }),
  },
// ...

There is also possibility to use array as a second argument to mapWaitingActions:

// ...
  methods: {
    ...mapWaitingActions('users', [
      'getUsers',
      { method: 'createUser', action: 'createUser', loader: 'creating user'},
      { method: 'createSuperUser', action: 'createUser', loader: 'creating super user' },
    ]),
  },
// ...

☢️Advanced Getters and Actions Usage

The Vuex module name is wait by default. If you've changed on config, you should get it by rootGetters['<vuex module name>/is'] or rootGetters['<vuex module name>/any'].

You can access vue-wait's Vuex getters using rootGetters in Vuex.

getters: {
  cartOperationInProgress(state, getters, rootState, rootGetters) {
    return rootGetters['wait/is']('cart.*');
  }
},

And you can start and end loaders using wait actions. You must pass root: true option to the dispatch method.

actions: {
  async addItemToCart({ dispatch }, item) {
    dispatch('wait/start', 'cart.addItem', { root: true });
    await CartService.addItem(item);
    dispatch('wait/end', 'cart.addItem', { root: true });
  }
},

waitFor(loader String, func Function [,forceSync = false])

Decorator that wraps function, will trigger a loading and will end loader after the original function (func argument) is finished.

By default waitFor return async function, if you want to wrap default sync function pass true in last argument

Example using with async function

import { waitFor } from 'vue-wait';

...
methods: {
  fetchDataFromApi: waitFor('fetch data', async function () {
    function sleep(ms) {
      return new Promise(resolve => setTimeout(resolve, ms));
    }
    // do work here
    await sleep(3000);
    // simulate some api call
    this.fetchResponse = Math.random()
  })
}
...

See also examples/wrap-example

💧 Using v-wait Component

If you disable registerComponent option then import and add v-wait into components

import vLoading from 'vue-wait/src/components/v-wait.vue'
components: {
  'v-wait': vLoading
}

In template, you should wrap your content with v-wait component to show loading on it.

<v-wait for='fetching data'>
  <template slot='waiting'>
    This will be shown when "fetching data" loader starts.
  </template>

  This will be shown when "fetching data" loader ends.
</v-wait>

Better example for a button with loading state:

<button :disabled='$wait.is("creating user")'>
  <v-wait for='creating user'>
    <template slot='waiting'>Creating User...</template>
    Create User
  </v-wait>
</button>

🔁 Transitions

You can use transitions with v-wait component.

Just pass <transition> props and listeners to the v-wait with transition prop.

<v-wait for="users"
  transition="fade"
  mode="out-in"
  :duration="1000"
  enter-active-class="enter-active"
  @leave='someAwesomeFinish()'
  >
  <template slot="waiting">
    <p>Loading...</p>
  </template>
  My content
</v-wait>

⚡️ Making Reusable Loader Components

With 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.

In 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:

<template lang='pug'>
  <div>
    <v-wait for="fetching tabs">
      <template slot="waiting">
        <b-tabs>
          <template slot="tabs">
            <b-nav-item active="active" disabled>
              <v-icon name="circle-o-notch" spin="spin" />
            </b-nav-item>
          </template>
        </b-tabs>
      </template>
      <b-tabs>
        <template slot="tabs">
          <b-nav-item v-for="tab in tabs">{{ tab.name }}</b-nav-item>
        </template>
      </b-tabs>
    </v-wait>
    <v-wait for="fetching data">
      <table-gradient-spinner slot="waiting" />
      <table>
        <tr v-for="row in data">
          <!-- ...-->
        </tr>
      </table>
    </v-wait>
  </div>
</template>

You may want to design your own reusable loader for your project. You better create a wrapper component called my-waiter:

<!-- MySpinner.vue -->
<i18n>
  tr:
    loading: Yükleniyor...
  en:
    loading: Loading...
</i18n>

<template>
  <div class="loading-spinner">
    <v-icon name="refresh" spin="spin" />
    <span>{{ $t('loading') }}</span>
  </div>
</template>

<style scoped lang="scss">
  .loading-spinner {
    opacity: 0.5;
    margin: 50px auto;
    text-align: center;
    .fa-icon {
      vertical-align: middle;
      margin-right: 10px;
    }
  }
</style>

Now you can use your spinner everywhere using slot='waiting' attribute:

<template lang="pug">
  <v-wait for="fetching data">
    <my-waiter slot="waiting" />
    <div>
      <p>My main content after fetching data...</p>
    </div>
  </v-wait>
</template>

📦 Using with external spinner libraries

You can use vue-wait with another spinner libraries like epic-spinners or other libraries. You just need to add slot="waiting" to the component and Vue handles rest of the work.

First register the component,

import { OrbitSpinner } from 'epic-spinners';
Vue.component('orbit-spinner', OrbitSpinner);

Then use it in your as a v-wait's waiting slot.

<v-wait for='something to load'>
  <orbit-spinner
    slot='waiting'
    :animation-duration="1500"
    :size="64"
    :color="'#ff1d5e'"
  />
</v-wait>

... and done!

For other libraries you can use, please see Loaders section of vuejs/awesome-vue.

🚌 Run example

Use npm run dev-vuex, npm run dev-vue or npm run dev-wrap commands. for running examples locally.

✔ Testing components

You can test components using vue-wait but it requires configuration. Let's take a basic component for instance:

<v-wait for="loading">
   <Spinner slot="waiting" />
   <ul class="suggestions">
      <li v-for="suggestion in suggestions">{{ suggestion.Name }}</li>
   </ul>
</v-wait>
const localVue = createLocalVue();
localVue.use(Vuex); // optionally when you use Vuex integration

it('uses vue-wait component', () => {
    const wrapper = shallowMount(Suggestions, { localVue });
    expect(wrapper.find('.suggestions').exists()).toBe(true);
});

vue-test-utils will replace v-wait component with an empty div, making it difficult to test correctly.

First, make your local Vue instance use vue-wait,

const localVue = createLocalVue();
localVue.use(Vuex); // optionally when you use Vuex integration
localVue.use(VueWait);

Then inject the wait property using VueWait constructor,

it('uses vue-wait component', () => {
    const wrapper = shallowMount(SuggestedAddresses, {
      localVue,
      wait: new VueWait()
    });
    expect(wrapper.find('.suggestions').exists()).toBe(true); // it works!
});

For Development on vue-wait

Install packages

$ yarn install
# or if you using npm
$ npm install

Bundle it

$ yarn bundle
# or if you using npm
$ npm run bundle

🎯 Contributors

  • Fatih Kadir Akın, (creator)
  • Igor, (maintainer, made Vuex-free)

🔗 Other Implementations

Since vue-wait based on a very simple idea, it can be implemented on other frameworks.

  • react-wait: Multiple Process Loader Management for React.
  • dom-wait: Multiple Process Loader Management for vanilla JavaScript.

🔑 License

MIT © Fatih Kadir Akın

vue-wait's People

Contributors

arioth avatar arthurn avatar benlind avatar dependabot[bot] avatar f avatar fraparisi avatar gabrielrobert avatar hosmelq avatar jonasmunck avatar justinmoon avatar koc avatar m3rc3d avatar maciekkus avatar moosjon avatar mosinve avatar pfacheris avatar pooot avatar sametaylak avatar sinanmtl avatar sky-code avatar yoyoys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-wait's Issues

wrapLoading undefined in v0.4.0

Trying to run

import { wrapLoading } from "vuex-loading"

console.log( wrapLoading ); // undefined

Guessing this is because the dist file hasn't been updated for v0.4.0?

Transition breaking changes

Hey!

First of all, I wanna thank you for such a good job you're doing!

The problem I wanna draw your attention to is about transition. After you introduced the transition element our application got broken. So here's the thing, if we send multiple elements as content for v-wait, Vue is complaining about multiple elements inside of transition and asking to use transition-group instead.

We can easily fix it by wrapping content into div, but as long as it's something that pretty hard to debug, you might want to do it on vue-wait side

Thanks!

[Vue warn]: You are using the runtime-only build of Vue

Hello,

I use .vue files for my components and webpack.
I tried to use v-loading component on my template, and i get this error at runtime:

vue.runtime.esm.js:570 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available.

Any ideas?

thanks

FR: Usage with namespaced Vuex modules

Splitting a Vuex store in one of my projects into namespaced modules made me think of the following.

Current way to use vue-wait with namespaced Vuex modules seems to be:
(Not documented btw.)

import { mapWaitingActions } from 'vue-wait'

// ...
  methods: {
    ...mapWaitingActions('users', {
      'user/getUser': 'loading the user',
    }),
  },
  mounted() {
    // get the user data
    this.user = this['user/getUser'](this.userId);
  },
// ...

I think something like this would be more preferable:

import { mapWaitingActions } from 'vue-wait'

// ...
  methods: {
    ...mapWaitingActions('users', {
      getUser: ['user/getUser', 'loading the user'],
    }),
  },
  mounted() {
    // get the user data
    this.user = this.getUser(this.userId);
  },
// ...

Thanks.

Renaming the repo

Since vuex-loading is not really Vuex related now, we need a new name. vue-loading is registered.

Maybe we can find a fancier (hipster) name. Should we use vue- prefix?

Typo: vuex-example

Hello!
In examples/vuex-example/main.vue there is ...mapWaitingActions({ incrementAsync: 'incrementing count', }), , where string is "incrementing count", but in usage above there is <v-wait for="incrementing" message='incrementing...'>, where "for" is equal to "incrementing". I think it should be equal to "incrementing count". Could you please fix this?

WaitFor is broken

I can't use waitfor helper for any situation.
Here is how I install the VueWait instance.

I think i need a waitFor method from wait instance, but it had nothing.

import VueWait from 'vue-wait';

...
new Vue({
....
 wait: new VueWait({ useVuex: true })
})

alternative for startLoading in Vuex actions?

I was using previous startLoading decorator function and I don't understand how it can be replaced from the new documentation. Can you maybe point me to the right direction?

Here is my example usage with vuex-loading:

dispatch('setActivities', await startLoading(dispatch, 'fetch activities', () => Activity.fetchAll()))

Add decorators

For now we need add to much mess code for using loading. Initiate start loading before action calling and call stop loading before each return or inside finally block. Is it possible enhance library with decorators? To add only one decorator above action.

vue-element $loading scope name collision issue

Goal: Combine vue-element with vuex-loading (without vuex)
Issue: The $loading property is already added to the instance by vue-element

I tried to add the configurable option loadingName, but i.e. options.parent["loader"] stays undefined.

How to solve that?

// vuex-loading.js
Vue.mixin({
    /**
     * VueLoading init hook, injected into each instances init hooks list.
     */
    beforeCreate () {
      const options = this.$options
      if (options.VueLoading) {
        this[options.loadingName] =
          typeof options.VueLoading === 'function'
            ? new options.VueLoading()
            : options.VueLoading
        this[options.loadingName].init(Vue, options.store) // store injection
      } else if (options.parent && options.parent[options.loadingName]) {
        console.log(this[options.loadingName])
        this[options.loadingName] = options.parent[options.loadingName]
        this[options.loadingName].init(Vue, options.parent.$store)
      }
    }
  })

Migrating from vuex-loading

Are there some basic instructions or maybe an issue (that I wasn't able to find) about dropping vuex-loading and moving to vue-wait?
For example,
createActionHelpers is not there anymore, what do we replace that with?
Thanks!

Consider v-show instead of v-if for v-wait component

I noticed while I was uisng the v-wait component, my component that I was wrapping was being created twice. First on initial load, then again after my call to my API to load the data. Looking over the source and the vuejs docs I saw this:

https://vuejs.org/v2/guide/conditional.html#v-if-vs-v-show

Which states that:

"...child components inside the conditional block are properly destroyed and re-created during toggles"

I wonder if it would be better for v-wait to use v-show instead? Or add an option?

How to use unit test with vuex-loading

I would like to write a unit test with the async action such as:
File navigation.spec.js:
`

import Vue from 'vue'
import Vuex from 'vuex'
import Vuetify from 'vuetify'
import vueLoading from 'vuex-loading'
import { shallow, createLocalVue } from '@vue/test-utils'
import Navigation from '@/components/Navigation'
import { stat } from 'fs';

Vue.use(Vuetify)
Vue.use(vueLoading)

const localVue = createLocalVue()
localVue.use(Vuex)

describe('Navigation', () => {
let store
let actions
let state

beforeEach(() => {
state = {
items: []
}

actions = {
  getAsync: jest.fn()
}

store = new Vuex.Store({
  state,
  actions
})

})

it('dispatches an getAsync action', () => {
const wrapper = shallow(Navigation, {
store,
localVue
})
wrapper.find('button').trigger('click')
expect(actions.getAsync).toHaveBeenCalled()
})
})

`

File Navigation.vue:
`

  
Loading... Call ajax
call ajax...
  • {{ item.title }}
    {{ item.body }}
<script> import { mapState, mapActions } from 'vuex' export default { name: 'RecipeNavigation', computed: { ...mapState(['items']) }, methods: { ...mapActions(['getAsync']), fetchResults () { this.getAsync() }, onClose () { this.$emit('close', this.$el) } } } </script>
`

The result of test:
[Vue warn]: Error in config.errorHandler: "TypeError: Cannot read property 'isLoading' of undefined"

Please help me to pass this issue. Thank you for any help you can offer

Proposal: extend createActionHelpers api

Hi, I have a proposal: add 2 action helpers - mapActions and mapDecoratedActions

https://gist.github.com/fxmaxvl/9353355f352561376812e90cff6a8a8b

mapActions:
It just extends action's context and provides $loading property with startLoading and endLoading helpers.
It makes module's actions code cleaner and more testable.

mapDecoratedActions:
It wraps action in try/finally block.
It can significantly reduce a boilerplate code with startLoading / endLoading.

vuex-loading is undefined

The new version 0.2.5 seems to be broken.

import VueLoading from 'vuex-loading'
console.log(VueLoading) // output undefined

Vue Wait with Typescript

I think that in Readme should be present a section for using this plugin in typescript.
To add the property "wait" to new Vue({wait: new VueWait()}) you need to define a type definitions like the one attached, otherwise will be raised an error because the property does not exist.
vue-wait-property.d.ts.zip

It does not work Internet Explorer 11

This loader realy amazing and I'm happy to see made by a turkish people something open source.

when I use $wait.is('login'), error throw and everything stop working. Could you fix that, thanks.

[Vue warn]: Error in render: "TypeError: Object doesn't support property or method 'includes'"

Strange minification issue on Safari iphone

Hi,

There are some minification issues on Safari iphone because package.json points to dist/vue-wait.js instead of src/vue-wait.js.

"main": "dist/vue-wait.js",
Happens only on old Safari versions, below version 11.

Thanks.

What is dispatch?

In the Global Action Helpers example, a dispatch object is expected to be passed into the startLoading() method. What is this object and how do I find it? Thanks.

Different or customizable $loading property

I find this library extremely useful, but the used property name is causing problems for me.

For example I'm using it along with element-ui, which also defined a this.$loading field resulting in errors.

In VueJS documentation, there is the recommendation of giving such field unique names:
https://vuejs.org/v2/style-guide/#Private-property-names-essential

It would be great if the exposed field could be defined in the constructor options, or renamed entirely to something else like $vuexLoading

"waiter.match is not a function"

I have the following in a JSX render function:

loading={this.$wait.isWaiting( [ "myFirstLoader", "mySecondLoader" ] )}

And I recieve the error:
"TypeError: waiter.match is not a function" from utils.js

This only happens when passing an array to isWaiting.

dependency matcher causing UglifyJS Error

Using webpack3,
a package you use "matcher" cause: (I thought it was vue-wait but seems not)

ERROR in ... from UglifyJs
Unexpected character '`' ...

Not sure why it is like this, I had to put your package source as well as matcher in my source and transform with my babel setup.

I was using this starting vuex-loading and it happens when I recently upgrade to this.
I think it is because matcher does not transform the code but I am not sure...
You might want to try it out yourself cuz this can make lots of frontend people move away from vue-wait which is a awesome package.

Documentation: describe vuex getters

Documentation for vuex integration looks incomplete. Please show how to access vuex getters inside other getters. Like

    [Getters.cartOperationsInProgress]: (state: CartState, getters, rootState, rootGetters): boolean => {
        console.log('cartOperationsInProgress');

        return rootGetters['wait/is']('cart.*');
    },

Problem after build nuxt

I have problem Cannot assign to read only property 'message' of object '' after build nuxt. please fix it. thanks
Screenshot 2019-03-27 at 10 59 19 AM

Typo in README

The comment //It's optional, 'loading'by default. is (as far as I can see) wrong, default vuex module is wait.

new Vue({
  el: '#app',
  store,
  wait: new VueWait({
    useVuex: true, // You must pass this option `true` to use Vuex
    vuexModuleName: 'vuex-example-module' // It's optional, `loading` by default.
  }),
});

Big update of the whole project to be progress management for Vue

I want to add full set of features for tracking progress information (with backward compatibility) just by extending methods with optional parameters about progress.

Because this feature will transform this library from
Complex Loader Management for Vue/Vuex Applications
to Complex Progress Management for Vue/Vuex Applications , propose to rename this project to Vue-progress and change description to
Complex Progress Management for Vue/Vuex Applications
then we can rename this.$loading to this.$progress which is much better in my opinion.

This repo then will redirect to new repo.

This is not necessary but will reflect much better the project purpose

Allow for arrays in <v-wait> 'for' parameter

Right now, the v-wait component doesn't support passing Array of strings. The component works correctly with arrays under the hood ($waitInstance.is() accepts arrays as well), but it throws the prop validation error in the console.
Screenshot 2019-07-24 at 08 38 06

Package size exploded

Looks like the most recent change increased the dist file size by nearly 7x. Was this a mistake or was that really necessary to fix the mobile Safari issue?

Introduce ability to declare action by name from vuex module in mapWaitingActions when two actions in different modules has the same name

Hi,
Would this be possible to add support for different name for "waitingActions".
This could be useful especially when two actions has the same name in different modules.
Something like in the example code below.

...mapWaitingActions('vuex_module_name', {
  someActionFromModule: { waiter: 'this is waiter for someAction', action: 'actionName' } 
}),

Kind regards,
Maciek

[vuex] duplicate getter key: loading/isLoading

I'm trying add this plugin to non-SPA lagacy project. And there is an error with useVuex: true and multiple Vue instances on same page.

Looks like plugin tryes add getters for each instance and we got error from Vuex about getters already reistered

Unknown custom element: <v-wait> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Error:

Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.

app.js:

document.addEventListener('DOMContentLoaded', (event) => {
  if (document.getElementById('app')) {
    new Vue({
      el: '#app',

      store,

      wait: new VueWait(),

      components: {
        // ...
      }
    })
  }
})

It does not help:

wait: new VueWait({
  accessorName: '$wait',

  useVuex: true,
  vuexModuleName: 'wait',

  registerComponent: true,
  componentName: 'v-wait',

  registerDirective: true,
  directiveName: 'v-wait',
})

component.vue:

<template>
  <v-wait for="loading items">
    <template slot="waiting">
      <div>
        Loading the list...
      </div>
    </template>

    <ul>
      <li v-for="(item, index) in items" :key="index">
        {{item}}
      </li>
    </ul>
  </v-wait>
</template>

Why does this error occur?

Add support of wildcards

For example have 2 actions: addProductToCart, refreshCart. Each of they call startLoading(dispatcher, 'cart') on method enter and endLoading(dispatcher, 'cart') before each return. The problem occurs when addProductToCart calls refreshCart inside. End loading occurs too early.

It is similar to nested transactions.

add delay option

Sometimes the response is too fast (e.g. cache) so delay is good solution to avoid loading spinner if that's shows only for few milliseconds.

Here is my util fot that:

import { createActionHelpers } from 'vuex-loading'

import { delay } from 'lodash/function'

export function createDelayedLoading (options, wait = 1) {
  let actionHelpers = createActionHelpers(options)
  let { startLoading: startLoadingFn, endLoading: endLoadingFn } = actionHelpers
  if (wait) {
    let delayed = null
    actionHelpers = {
      startLoading: (dispatcher, loader, callback) => {
        delayed = delay(() => {
          startLoadingFn(dispatcher, loader, callback)
        }, wait)
      },
      endLoading: (dispatcher, loader) => {
        clearTimeout(delayed)
        endLoadingFn(dispatcher, loader)
      }
    }
  }
  return actionHelpers
}

What do you think about adding something similar to the project?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.