• Stars
    star
    276
  • Rank 149,319 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Universal Vue stores you write once and use anywhere

Vue Class Store

Universal Vue stores you write once and use anywhere

Vue Class Store logo

Abstract

So Vue, Vuex and Vue Class Store walk into a bar...

Vue says: "I'll give you reactivity, computed properties and watches, but only in components, only using a special objects-and-function schema, and I demand initial values be passed in from a parent component using props! I don't get along particularly well with TypeScript either, so good luck with figuring that one out, buddy"

Vuex says: "I'll give you global reactivity and computed properties, but I'm going to call them esoteric names and require you set them up globally with a convoluted schema, access them only through a centralised store, and I'll force you to make all updates through string-based paths, with different formats, helpers, terminology and best practices. I'll also make it difficult to go more than a couple of levels deep, and I'll give you watches but you'll hate them so probably best not to use those either"

Vue Class Store says: "I'll give you reactivity, computed properties and watches, written in standard JavaScript or TypeScript, with no setup or boilerplate, and you can use me anywhere"

The end

Usage

Installation

Install the package from NPM:

#vue 2
npm i vue-class-store@^2.0.0

#vue 3
npm i vue-class-store@^3.0.0

Yarn users, replace npm i with yarn add.

Declaration

Write classes as normal, and add the decorator @VueStore to those you want to become reactive.

import VueStore from 'vue-class-store'

@VueStore
export class Store {
  // properties are rebuilt as reactive data values
  public value: number

  // getters are converted to (cached) computed properties
  public get double (): number {
    return this.value * 2
  }

  // constructor parameters serve as props
  constructor (value: number = 1) {
    // constructor function serves as the created hook
    this.value = value
  }

  // prefix properties with `on:` to convert to watches
  'on:value' () {
    console.log('value changed to:', this.value)
  }

  // you can even drill into sub properties!
  'on:some.other.value' = 'log'

  // class methods are added as methods
  log () {
    console.log('value is:', this.value)
  }
}

Instantiation

To use a store, simply instantiate the class.

You can do this outside of a component, and it will be completely reactive:

const store = new Store({ ... })

Or you can instantiate within a component:

export default {
  ...
  computed: {
    model () {
      return new Store({ ... })
    }
  }
}

Alternatively, you can make any non-decorated class reactive on the fly using the static .create() method:

import VueStore from 'vue-class-store'
import Store from './Store'

const store: Store = VueStore.create(new Store({ ... }))

How it works

This is probably a good point to stop and explain what is happening under the hood.

Immediately after the class is instantiated, the decorator function extracts the class' properties and methods and rebuilds either a new Vue instance (Vue 2) or a Proxy object (Vue 3).

This functionally-identical object is then returned, and thanks to TypeScript generics your IDE and the TypeScript compiler will think it's an instance of the original class, so code completion will just work.

Additionally, because all methods have their scope rebound to the original class, breakpoints will stop in the right place, and you can even call the class keyword super and it will resolve correctly up the prototype chain.

devtools

Note that the object will of course be a Vue or Proxy instance, so running code like store instanceof Store will return false .

Inheritance

The decorator supports class inheritance meaning you can do things like this:

class Rectangle {
  width = 0
  height = 0
  
  constructor (width, height) {
    this.width = width
    this.height = height
  }
  
  get area () { return this.width * this.height }
}

@VueStore
class Square extends Rectangle {
  constructor (size) {
    super(size, size)
  }

  'on:width' (value) { this.height = value }
  'on:height' (value) { this.width = value }
}

Make sure you don't inherit from another decorated class because the original link to the prototype chain will have been broken by the substituted object returned by the previous decorator:

// don't do this!

@VueStore
class Rectangle { ... }

@VueStore
class Square extends Rectangle { ... }

If you need to keep the original Rectangle and Square intact, decorate a final empty class that leaves the original classes untouched:

// do this instead...

class Rectangle { ... }
class Square extends Rectangle { ... }

@VueStore
class SquareStore extends Square { } 

Alternatively, use inline creation:

import Square from './Square'

const model: Square = VueStore.create(new Square(10))

Global / shared state

Because the class itself is reactive, you could inject it into a component tree, simulating global state:

export default {
  provide () {
    return {
      $products: new ProductsStore()
    }
  },
}
export default {
  inject: [
    '$products'
  ],
  
  computed: {
    items () {
      return this.$products.items
    }
  },
  
  filterProducts (value) {
    this.$products.filter = value
  }
}

Development

Demo

The library has demos for Vue 2, Vue 3 and Nuxt, and can be found in the following repo:

Scripts

The package uses Yarn, and has only two scripts, to build for development and production:

  • yarn dev - build and watch for development
  • yarn build - build for production

More Repositories

1

vuex-pathify

Vue / Vuex plugin providing a unified path syntax to Vuex stores
JavaScript
1,393
star
2

javascript-state-machine

An expressive, feature-rich, event-driven JavaScript finite-state machine
JavaScript
345
star
3

laravel-sketchpad

An innovative front-end environment for interactive Laravel development
PHP
300
star
4

alias-hq

The end-to-end solution for configuring, refactoring, maintaining and using path aliases
JavaScript
297
star
5

nuxt-areas

Simple and scalable folder management for large Nuxt projects
JavaScript
231
star
6

axios-actions

Bundle endpoints as callable, reusable services
TypeScript
189
star
7

vue-trello-clone

A simple Trello clone
JavaScript
151
star
8

xjsfl

Rapid development framework for extending Adobe Flash
JavaScript
135
star
9

todo-emojis

Track todos in Slack using custom checkbox emojis
90
star
10

maxscript

Various MaxScripts and plugins created from 2001 - 2008
MAXScript
85
star
11

vee-element

Replaces Element UI's validation engine with Vee Validate
JavaScript
73
star
12

classic-shell-win10

A Windows 10 theme for Classic Shell / Classic Start Menu
HTML
60
star
13

great-suspender-recovery-tool

Recover your lost Great Suspender Tabs
JavaScript
56
star
14

nuxt-content-assets

Enable locally-located assets in Nuxt Content
TypeScript
55
star
15

vue-source

Identifies Vue components in DevTools Elements panel via HTML comments
JavaScript
41
star
16

app-diary

Ongoing development diary of building a Trello clone
JavaScript
32
star
17

got-paper

The official "got paper?" app – a Vue / Nuxt PWA, optimised for mobile, running in 12 languages
Vue
27
star
18

spaceman

Manage monorepo workspaces with a prompt-based CLI
JavaScript
25
star
19

outliner

A node package to outline SVG strokes as fills
JavaScript
24
star
20

minimap-font

An editor font to give you a 10,000ft view of the code
HTML
19
star
21

vuex-pathify-demos

A set of demos for the Vuex Pathify plugin
Vue
16
star
22

vue-enums

Easily use TypeScript enums in Vue SFC templates
JavaScript
11
star
23

vue-class-store-demos

Vue Class Store demos for Vue 2, Vue 3 and Nuxt
Vue
10
star
24

komodo-autocode

Adds extra functionality to Komodo that makes it easier than ever to write (and test) quality code
JavaScript
10
star
25

nuxt-areas-demo-vue2

Demo project to showcase Nuxt Areas functionality
Vue
7
star
26

jquery-populate

6
star
27

alias-quokka-plugin-demo

Demo project to test Quokka local ES6 imports in a scratch file
JavaScript
6
star
28

msal-vue-demo

A minimal but production-friendly Vue 3 / MSAL demo
TypeScript
5
star
29

flash-wowza-demo

OO version of the Wowza record / play demo
ActionScript
4
star
30

jquery-scroll-into-view

jQuery plugin to scroll an element into view
HTML
4
star
31

javascript-ascii

Output objects' structure in text / ASCII format
HTML
3
star
32

laravel-sketchpad-reload

Live-reload functionality for Laravel Sketchpad
JavaScript
3
star
33

flash-core

A robust set of base ActionScript 3.0 classes developed out of commercial projects
ActionScript
2
star
34

i-hate-computers

I hate computers
JavaScript
2
star
35

es-kit

A "pick and mix" library that simplifies writing Elasticsearch code
TypeScript
2
star
36

flat-file-api

A command line tool to mock APIs using flat files
JavaScript
2
star
37

nuxt-scrollbar

Nuxt wrapper for Vue 3 Perfect Scrollbar
Vue
2
star
38

flash-flashywrappers-demo

ActionScript
1
star
39

vuex-pathify-simple-demo

Simple Vuex Pathify standalone demo
JavaScript
1
star
40

php-apidoc

Demo repositoriry for APIDoc with sample API and automatic builds via Grunt
PHP
1
star
41

nuxt-layers-utils

A collection of utilities to work with Nuxt layers
1
star
42

nuxt-sockets

WebSockets solution for Nuxt
TypeScript
1
star
43

laravel-resourcery

A lightweight & flexible resource management system
PHP
1
star
44

handsontable-checkboxes-demo

Demo project to fix focus issues with custom editor
JavaScript
1
star
45

extension-vue-devtools

Webpack plugin to open and connect to external Vue Devtools
JavaScript
1
star
46

wp-template-redirect

Template to simply redirect to another URL, rather than load a post or page
1
star
47

vue-customer-query

Example Vue application
Vue
1
star
48

collection-fns

A set of flexible, type-safe functions to manipulate arrays of models
TypeScript
1
star
49

better-fastmail

UX & UI improvements to the FastMail web client
JavaScript
1
star