🌲
Spruce
  • Introduction
  • Installation
  • Quick Start
  • The Essentials
  • Stores
  • Watchers
  • Persistence
  • Advanced
    • Hooks
  • Examples
    • Global Toast System
  • More
    • GitHub
    • Funding
    • Security
    • License
Powered by GitBook
On this page
  • What is a store?
  • Creating a new store
  • Accepted data types
  • Accessing a store from Alpine
  • Accessing a store from JavaScript
  • Overwriting a store
  • Adding methods to stores
  • Getters and setters

Was this helpful?

Stores

Learn what a store is and how to create, modify and reset them.

What is a store?

A store is an object that holds global state. They are named objects, meaning different groups of global data can be accessed under a single name.

Stores are also reactive. Any changes made to a store will trigger a re-render on all Alpine components that are subscribed.

An Alpine component will be automatically subscribed to global state changes when it first accesses a piece of global state. There is no need to tell Spruce which components need to be re-rendered when state changes.

Creating a new store

You can create a store using the Spruce.store() method.

Spruce.store('user', {
    name: 'Ryan Chandler',
    email: 'support@ryangjchandler.co.uk',
})

The first argument is the name of the store. This should describe what data is being tracked inside of the store. The second argument is the state itself.

Accepted data types

When defining a store, you will most likely be using an object or array to hold your data. However, Spruce also supports using scalar values such as string, int or boolean as the data type.

Spruce.store('name', 'Ryan Chandler')

The Spruce object is defined on the windowobject, therefore accessing it inside of a bundled file (or outside of the global scope) will require you to use window.Spruce instead.

Spruce also accepts a function as the second argument. This function should return the store's state, similar to function-based components in Alpine.

Spruce.store('user', function () {
    let user = window.User
    
    /* Do some stuff with `user` here */
    
    return {
        name: user.name,
        email: user.email,
    }
})

Accessing a store from Alpine

To access a store from an Alpine component, Spruce provides a magic $store variable. This is an object that holds each store under a property.

For example, to access tthe user store above, you would use $store.user.name inside of your Alpine component.

<span x-data x-text="$store.user.name">
    <!-- outputs "Ryan Chandler" -->
</span>

Previous versions of Spruce required the user of an x-subscribe directive on the root element. Since 1.x, this is no longer needed. The $store variable is automatically available for use in your components.

If you are accessing the $store variable from inside a function on your component, you must use this.$store instead.

function componentData() {
    return {
        getName() {
            return this.$store.user.name;
        }
    }
}

Accessing a store from JavaScript

If you would like to access a store inside of a JavaScript file or <script> tag, you can use the Spruce.store() method too. Pass the name of the store, omitting the second argument.

Spruce.store('user', {
    name: 'Ryan Chandler',
    email: 'support@ryangjchandler.co.uk',
})

const userStore = Spruce.store('user')

console.log(userStore.name)

This will return the underlying Proxy which can be used to access all of your state.

Overwriting a store

If you wish to overwrite, or redefine, your store at runtime, you must use the Spruce.reset() method. This method will forcefully overwrite the current state.

Spruce.reset('user', {
    name: 'John Doe',
})

console.log(Spruce.store('user').name)  // "John Doe"
console.log(Spruce.store('user').email) // "undefined"

Adding methods to stores

Much like data objects in Alpine, you can define methods on your Spruce stores. These methods can then be called on the store object.

Spruce.store('user', {
    name: 'Ryan Chandler',
    email: 'support@ryangjchandler.co.uk',
    getFirstName() {
        return this.name.split(' ')[0]
    }
})

const userStore = Spruce.store('user')

console.log(userStore.getFirstName()) // "Ryan"

The this context of a method is bound to the store object itself, so you can access all of the defined properties.

Getters and setters

Spruce.store('user', {
    name: 'Ryan Chandler',
    email: 'support@ryangjchandler.co.uk',
    get firstName() {
        return this.name.split(' ')[0]
    }
})

const userStore = Spruce.store('user')

console.log(userStore.firstName) // "Ryan"
PreviousQuick StartNextWatchers

Last updated 4 years ago

Was this helpful?

Since Spruce generally uses to hold state, you can also define and on those objects.

"object literals"
getters
setters