Vue - How to use one plugin twice but with different settings?

Viewed 120

There is a plugin vue2-storage that allows you to use browser-based localStorage.

In the settings of this plugin, you can specify the prefix that will be used for keys.

In my Vue application, I need to store two kinds of data in localStorage: users and cars. These data are not related with each other and should not overlap.

The users example data:

evan {name: 'Evan', 'email': 'evan@mail.com'}
piter {name: 'Piter', 'email': 'piter@mail.com'}
eva {name: 'Eva', 'email': 'eva@mail.com'}
...

The cars data example:

А111АА11 {brand: 'Volkswagen', 'model': 'Polo', 'year': 2015, hp: 150}
А222АА22 {brand: 'BMW', 'model': 'X3', 'year': 2017, hp: 170}
А333АА33 {brand: 'Lada', 'model': 'Priora', 'year': 2008, hp: 98}
...

Is it possible to do something like this:

import Vue from 'vue';
import { Plugin } from 'vue2-storage';
Vue.use(Plugin, {prefix: 'users_'});
Vue.use(Plugin, {prefix: 'cars_'});

// And then use like this:
this.$usersStorage.set(...);
this.$carsStorage.set(...);
...

Of course, the above code will not work, because Vue does not allow you to use two identical plugins. Or how does that still allow?

Perhaps there is some workaround, in the form of creating some kind of your own wrappers over the methods of this plugin?

Or create two own plugins that will inherit from vue2-storage, but store themselves in the Vue application not just as this. $storage, but as this.$usersStorage and this.$carsStorage?

I understand that storing JSON objects in localStorage is not quite the right approach, and IndexedDB is probably a more suitable option for this. But there will be very little data, only about 10 records, and I don't really want to use the more extensive IndexedDB for them.

2 Answers

A lot of third-party Vue plugins just expose some instance to the application, this can be seen here.

This requires to work around library internals in some cases to produce multiple instances, but this one provides original class as default export.

Instead of using existing plugin, for Vue 2 this can be as simple as

Vue.prototype.$foo = new Vue2Storage(...);
Vue.prototype.$bar = new Vue2Storage(...);

The use of global namespace for local purposes is a bad practice that comes from the time when Vue wasn't used with ES modules. foo and bar can be local singletons and imported in places where they are used.

A bit off the point of the question, but Vuex + vuex-persistedstate worked well for solving the problem.

Related