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

vue-class-stores

v0.0.62

Published

Use classes to handle state in vuejs. This is a webpack plugin that will generate type definitions and globally init your stores. Topics Resources

Downloads

101

Readme

Vue Class Stores

To quickly get started, you can navigate into the apptest directory to view a full working example. There's also a webpack.config.js showing the implementation... or you can continue reading.

Why?

For a while I've been doing my stores this way... but explaining to others how it works, how to generate the type definitions etc, was a little difficult. It's also become a pain in the ass to assign the stores to the vue prototype & manually update the type definitions. This package will take care of the type definitions and vue prototype manipulation to instantiate your stores.

I love managing my stores this way. Since I learned this method I can't go back, I also cannot stand React for this one single point. I like OO logic/structure to my applications.

You can put your state and any methods you need all together in one store. Which can be used anywhere in your application, and it will keep it's state + stay reactive.

Imagine you have some blog posts state, have a websocket connection which receives new blog posts. You can directly push these posts into the state from an entirely different class/location.

Getting Started

Installing the package

npm install vue-class-stores typesafe-local-storage 
yarn add vue-class-stores typesafe-local-storage 

typesafe-local-storage is one of my other packages that make some features of this package a little easier to build/work with. You should take a look at them also, they may help you with other things :)

Configuring Webpack

Add the plugin to your webpack configuration:

const {WebpackClassStoresLoader} = require('vue-class-stores/Webpack');

module.exports = {
  plugins : [
    new WebpackClassStoresLoader()
  ]
}

Plugin Configuration

| Option | Type | Default Value | Info | | ------------------- | ------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | usingTypescript | boolean | false | Ensures generated files use the correct extensions | | pluginDirectory | string | src/Stores/Plugin | Where the generated vue plugin will be stored | | storesDirectory | string | src/Stores | Where your vue stores are located | | shortVueDeclaration | boolean | false | If the store "UserStore" is defined, you will reference it via "user" or "$user" when short === true, otherwise userStore or "$userStore". |

Setting your configuration via the webpack plugin:

You can provide an object to the webpack plugin. Though, with this way, these options won't be used when you use the [Generate Command](#Generate plugin/store files). So the next method is suggested.

new WebpackClassStoresLoader({
  // true = Using typescript
  // false = Using javascript
  // Ensure you set this correctly!  
  usingTypescript : false,
  // Where you want type definitions and the plugin to be defined
  pluginDirectory : 'src/Stores/Plugin',
  // Where your store classes are located
  storesDirectory : 'src/Stores',
  // When creating the global vue reference
  // shortVueDeclaration = true = $user
  // shortVueDeclaration = false = $userStore
  shortVueDeclaration : false,
})

Defining your configuration in package.json

You would only really need to do this when using the [Generate Command](#Generate plugin/store files) listed below

{
  "vue-class-stores": {
    "usingTypescript": true,
    "shortVueDeclaration": true,
    "pluginDirectory": "src/Stores/Plugin",
    "storesDirectory": "src/Stores"
  }
}

Generate plugin/store files

If webpack errors whilst building, the plugin won't generate its files... which could be the case in some scenarios.

It's also handy for when getting everything set up.

./node_modules/.bin/vue-class-stores-generate

Run a build of your application

Now if you navigate to /src/Stores/ you will see a Plugin directory. These are the files that this package has built for you.

Final Setup Steps

The package will automatically determine your vuejs version and generate files/code that will work with your version. However... there's some additional steps dependent on that version.

Vue 2

The package needs to use features from the composition api, which vue 2 doesn't have... however, you can install the vue composition api into vue2. I tried my best to avoid having to do this, but having the ability to watch a vue object for changes isn't as easy as it sounds.

npm install @vue/composition-api
yarn add @vue/composition-api
Add the plugin to your vue app
// Make sure to add this import before VueClassStoresPlugin 
// or composition api may complain
import './Stores/Plugin/InstallVueCompositionApi';
import {VueClassStoresPlugin} from "./Stores/Plugin/VueClassStoresPlugin";

Vue.use(VueClassStoresPlugin);

const app = new Vue({el : "#app"});

Vue 3

Add the plugin to your vue app
import {VueClassStoresPlugin} from "./Stores/Plugin/VueClassStoresPlugin";

const app = createApp();
app.use(VueClassStoresPlugin)

How to work with the stores?

Creating a store

If you're using typescript, you can create a type for your store object and provide this as a generic to the Store class

import {Store} from "./Plugin/Store";
import {store, watch} from "vue-class-stores"

type UserStoreState = {
  user: AuthedUser | null;
}

// You need to define the @store decorator
@store()
export class UserStore extends Store<UserStoreState> {

  initialState(): UserStoreState {
    return {
      user : null
    }
  }

  setUser(user: AuthedUser) {
    this.state.user = user;
  }

  get authedUser(): AuthedUser | null {
    return this.state.user;
  }

  // You can also define watchers on the store
  // You can name the method anything

  // The 'user' string is the name of our state property 
  // that we wish to watch for changes on.
  @watch('user')
  onUserUpdated(value: AuthedUser) {
    console.log('Our authed user was updated!', value)
  }
}

Using the store in your components

SFC Script


<script>
import {user, useUserStore} from '@src/Stores/Plugin/VueStores';

export default defineComponent({
  // We can use it in the options api
  mounted()
  {
    // We can use the following methods to access the store
    this.$user.setUser(new User({username : 'Sam'}));
    user.setUser(new User({username : 'Sam'}));
  },

  // Or we can use composition api
  setup()
  {
    const userStore = useUserStore();

    userStore.setUser(new User({username : 'Sam'}));

    return {user}
  }
})
</script>

SFC Html


<template>
  <div>
    <!-- In our template, we can use $user or $userStore to reference the store -->
    <!-- Depending on our "shortVueDeclaration" configuration setting -->
    <p>
      The authed user is: {{$user.authedUser === null ? 'Nobody' : $user.authedUser.username }}
    </p>
  </div>
</template>

Using the store from outside components

Imagine we have some logic that handles our internal authentication flow and we wrapped these methods in a class.

export default class Authentication {
  public async login(username: string, password: string) {
    // ... some login api request
    const response = await Api.login(username, password);

    userStore.setUser(new AuthedUser(response));
    userStore.state.authenticated = true;
  }
}

Using a method like this, all of our components will update to match this authenticated state + the authenticated user.

Persisted Stores

Persisted stores are the same stores, except it will store your state in local storage and re-populate it when the browser loads the page again.

It will also do it's best to make sure all of the types match, for example, in our AuthedUser example above. It will ensure that the AuthedUser class is set on the state again with the same properties to avoid any issues.

It's super simple to enable persistence, using our UserStore example from further up, we can just change the decorator:

import {Store} from "./Plugin/Store";
import {persistedStore, watch} from "vue-class-stores"

type UserStoreState = {
  user: AuthedUser | null;
}

// You need to define the @store decorator
@persistedStore()
export class UserStore extends Store<UserStoreState> {

  initialState(): UserStoreState {
    return {
      user : null
    }
  }

  // We can define this method if we'd like to specify
  // Some logic that is run when our store is re-populated from storage
  onLoadedFromStorage() {
  }
}

Explanation of generated files:

VueCompositionApiExports - This just exports the methods from the vue composition api if you're using vue 2. Files will used the exports from that file. It keeps things simple when generating all of those code.

InstallVueCompositionApi - VueClassStores plugin will instantiate all of your stores. If vue composition api is not "installed" yet then it will complain. The logic is extracted into this file so that it can be placed at the top of your main app file and be the first to run, also in a separate scope to VueClassStoresPlugin

VueClassStoresPlugin - This is an auto generated plugin for initiating your stores and registering them with Vue.

VueStores - This is an export of all your stores that will maintain state, it will allow you to use your stores in different classes and such.

VueClassStoresPluginTypes.d.ts - This should help your ide understand that you're using a store in your vuejs templates and understand that they're registered with Vue.

Store - All of your store classes should extend this class. It's automatically generated depending on your vue project version. It just provides some basic functionality for everything to work easily.

stores.meta.json - This file is incase you need to look at any of the data used for generating files. Or would like to add some further dynamic logic on top of what vue-class-stores provides.