npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@oarepo/vuex-preloader

v1.3.5

Published

Preloader library (not only) for OARepo

Downloads

62

Readme

@oarepo/vuex-preloader

A url-parameters based preloader for vuex stores

What it does

This library provides a preloader that listens on router changes (beforeEach) and calls action on a vuex store before the execution is passed to target vue component.

When the route is changed, the preloader looks for meta.preloader section of matched route segments (all the way up to the root). For each of the preloader segment it calls load method on the appropriate store. The methods are called in the order from the root down to the end of the matched path.

Installation

yarn add @oarepo/vuex-preloader

Configuration

In main.js/quasar boot, register the preloader:

import VuexPreloader from '@oarepo/vuex-preloader'

function errorHandler({router, route, pathSegment, exception}) { 
    console.error('Exception detected')
    return '/error/404'
}
Vue.use(
    VuexPreloader, 
    {
        router, store, 
        errorHandler, 
        debug: true
    }
)

In routes, make sure that routes are named and add the meta sections:

const routes = [
    {
        path: '/',
        name: 'home',
        component: Home,
        meta: {
            preloader: {
                'store': 'articles',
            }
        }
    },
    {
        path: '/:articleId',
        name: 'article',
        component: () => Article,
        meta: {
            preloader: {
                'store': 'article',
                'action': 'loadArticle',
                'params': {
                    articleId: 'id'
                }
            }
        },
        children: [
            {
                path: '/comments',
                name: 'comments',
                component: () => Comments,
                meta: {
                    preloader: {
                        'isolated': commentStoreFactory,
                        'action': 'loadComments',
                        'params': {
                            articleId: 'articleId'
                        }
                    }
                }
            }
        ]
    }
]

With this configuration, if user navigates to /12/comments, a loading action is dispatched on two stores - at first on article store and then comment store - and after the loading has finished route is changed and Comments component is shown.

Parameters inside meta.preloader:

  • store - use this store module. If not filled, use the whole store

  • isolated - the parameter is a function that returns a vuex module. The module is instantiated and registered via store.registerModule with a random name (prefixed with instantiated_module.vuex_name) When the module is not needed (user navigates out of the path segment), it is automatically removed from the main store.

  • action - dispatch this action on the store. Default action is load

  • params - if filled, pass only these arguments to the store. The key is the name of path parameter, the value is the name of the passed parameter to the action. If not filled, all path parameters are passed to the store's action.

  • props - extra static props that will be passed to the store

  • reload - if set to true, always dispatch the action. If set to false (default), dispatch the action only when the parameters to the action call have changed.

  • expiration - if set, store will not be reloaded if expiration (in seconds) has not passed since the last load

  • reloadInterval - if set, store will be reloaded automatically each reloadInterval (if the path still matches)

The path is changed only if all actions succeed in loading. If they do not, an error handler is called with object {router, route, pathSegment, exception}. The handler can return:

  • true to continue loading
  • false to stop path change. The handler is responsible for communicating the error and/or calling router.navigate
  • new route to use it as the next url - page will be changed to this (for example, 404 page)

Multiple loaders on one path

The library supports multiple preloaders on a single route. Just put the loaders into an array, such as in:

const routes = [
    {
        path: '/:articleId',
        name: 'article',
        component: () => Article,
        meta: {
            preloader: [{
                'store': 'article',
                'action': 'loadArticle',
                'params': {
                    articleId: 'id'
                }
            },
            {
                'store': 'comments',
                'action': 'loadArticleComments',
                'params': {
                    articleId: 'id'
                }
            }]
        }
    }
]

Single store on multiple paths

For cases where two paths reference the same loader, the loader would not reload as the remembered previous state is recorded on each path and so the loader does not know that a store content's has changed.

To fix this issue, manually set on all preloaders the same key property, such as:

const routes = [
    {
        path: '/:articleId',
        name: 'article1',
        component: () => Article1,
        meta: {
            preloader: {
                'key': 'article',
                // extra params here
            }
        }
    },
    {
        path: '/:articleId',
        name: 'article2',
        component: () => Article2,
        meta: {
            preloader: {
                'key': 'article',
                // extra params here
            }
        }
    }
]

Reloading

In the default settings, store is only reloaded if the params for the fetch method have changed (i.e. the params in the url for the given route has changed). This setting can be overridden on many levels:

reload

if this option is set to true, the store will reload anytime the url is hit

expiration

if this option is set, the reload will happen on url change whenever the current time is greater than the time of the last fetch + expiration.

reloadInterval

if the route is shown to the user, the store will reload every reloadInterval seconds

store.reloadNeeded

additionally if there is a property on the store called reloadNeeded and it is set to true, the store will be reloaded when the url is hit.

Store name injection

The library can also inject actual store name and additional properties into the component responsible for the path segment. To use this functionality (for example in case of isolated stores), register:


registerPreloader(router, store, erorrHandler, {injection: true})

Implicitly storeName is injected into the component's props. When using isolated factory, all properties returned by the factory are injected as well.

vue-query-synchronizer integration

It is possible to use this library together with vue-query-synchronizer. This way the default values (such as pageSize=10, if not found in query) are stored in one place in query synchronizer. An example ('1' is the default value of filter):

routePart = {
        path: '/vue-query-synchronizer',
        name: 'vueqs',
        component: VueQS,
        meta: {
            preloader: {
                'store': 'qs',
            }
        },
        props: query([
            'string:filter:1',
        ], {}, {
            passParams: true,
        })
    }

The library can also enable you to store/retrieve the default value to localStorage/server so that when user opens the application he sees his previous preset values (such as default number of table rows):

routePart = {
        path: '/vue-query-synchronizer',
        name: 'vueqs',
        component: VueQS,
        meta: {
            preloader: {
                'store': 'qs',
            }
        },
        props: query([
            'number:pageSize',
        ], {}, {
            passParams: true,
            onInit (params) {
                params[0].defaultValue = window.localStorage.getItem('pageSize') || '10'
                return params
            },
            onChange (newQuery, query) {
                window.localStorage.setItem('pageSize', query.pageSize || '')
            }
        })
    }

See https://github.com/oarepo/vue-query-synchronizer for details on using this library.

Project setup

yarn install

Sample application

To see the library in action, run the sample application

yarn run serve

Compile the library

yarn run build