Values - Raiondesu/Tuex GitHub Wiki

A Native JavaScript Concept

As it was said previously, Tuex relies moslty on native JS concepts, which feel intuitive if you already know JavaScript and help to adapt to any desirable internal store architecture.

One of such concepts is called Value.

What is it?

Value is, basically, what it sounds like - it's a pure property of an object that isn't a pointer nor a reference (more on those later). So, simply put, values can only be one of what's called primitive types.

For example, if we were to convert a specific object to a Tuex-store:

const obj = {
  // This one is a value
  value: 12,

  // This one is a value
  valueToo: 'foobar',

  // This one is not
  notValue: () => 12
}

Tuex-Enhanced Values

Tuex does two very useful things to the object's values: makes them reactive and tracks their activity.

It means that whenever the value is accessed or whenever anything is assigned to it, Tuex instantly knows about this.

...
const tuex = new Tuex.Store({
  num: 0
});

console.log(tuex.store.num); // => 0
// Tuex gets notified here that the value 'num' has been accessed

tuex.store.num = 10;
// Here too Tuex gets notified that 10 is being assigned to the value 'num'
...

Enumerable

Values in Tuex are the only enumerable properties of store. This makes them easy to access separately from getters, setters and methods, i.e.

const tuex = new Tuex.Store({
  value: 12,
  valueToo: 'foobar',
  notValue: () => 12
});

console.log(Object.keys(tuex.store));
// => [ 'value', 'valueToo' ]
// Only values' keys get logged out

for (let key in tuex.store) {
  // Here, key can be only one of 'value' or 'valueToo'
}

console.log(JSON.stringify(tuex.store));
// => { "value": 12, "valueToo": "foobar" }

Getting Tuex values into Vue Components

Imagine we want to display our store's value in some component:

Vue.use(Tuex);

const tuex = new Tuex.Store({
  count: 0
});

The following text contains examples and text from Vuex documentation

So how do we display state inside the store in our Vue components? Since Tuex stores are reactive, the simplest way to "retrieve" value from it is simply returning some store value from within a computed property:

// let's create a Counter component
const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return tuex.store.count
    }
  }
}

Whenever store.count changes, it will cause the computed property to re-evaluate, and trigger associated DOM updates.

However, this pattern causes the component to rely on the global store singleton. When using a module system, it requires importing the store in every component that uses store state, and also requires mocking when testing the component.

Tuex provides a mechanism to "inject" the store into all child components from the root component with the store option (enabled by Vue.use(Tuex)):

const app = new Vue({
  el: '#app',
  // provide the store using the "store" option.
  // this will inject the store instance to all child components.
  store,
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

By providing the store option to the root instance, the store will be injected into all child components of the root and will be available on them as this.$store. Let's update our Counter implementation:

const Counter = {
  template: `<div>{{ count }}</div>`,
  computed: {
    count () {
      return this.$store.count
    }
  }
}

Enforcing Flux pattern

The Flux's (and Vuex's) approach to disallow any modification of store's values can be simulated by the use of the strict flag. Enabling it disallows the changes of store's values, forcing to make them through setters (mutations).

⚠️ **GitHub.com Fallback** ⚠️