BLACKFYRE
MG—01
LANG
←
ALL POSTS
05 · Writing / 2018
07 DEC 2018 · 3 MIN READ

Laravel Nova & Vuex… a future proof solution?!

Since Nova 1.2 the root Vue instance has a Vuex store. Register your tool's module on it with registerModule, no patching required.

CONTENTS
04 +

If you follow my stories, you probably know by now that I’ve got an ongoing fight to get Vuex properly working with my Laravel Nova admin site.

Enlarge imageA freshly generated Nova tool: the Media Manager page saying “We’re in a black hole.”
FIG. 1Where every Nova tool starts: the generated Tool.vue, waiting for a store.

A quick recap

The first iteration was to attach a Vuex store to the Nova global object, which works… but not an ideal one…

The second trial was to modify the source files of Nova to access the root creation and append my Vuex store there. (This is a viable approach if you don’t install Nova through Composer.) This approach was quickly deprecated by version 1.1.9, which added Vuex, and since then some parts of Nova use it as well.

A solution?!

After Nova 1.2 we have a modular Vuex store available on the root instance (where its proper place is), and it’s accessible through the this.$store object! This enables us to do lots of “evil & nasty” things 😈

  1. You’ll need to install Vuex for your tool / resource tool.
  2. In your tool’s resources/js/components/Tool.vue file, in the created() lifecycle hook, you can dynamically register your store object with this.$store.registerModule().
  3. To use the store, you can access the state through the this.$store object, or (my favourite) the map helpers: mapGetters, mapActions, …

Step by step

Installing Vuex in the tool is only needed for the map helpers. The store itself is Nova’s, so the tool never creates one:

SHELL
npm install vuex --save

The module is the same set of files as in the previous articles, bundled up and namespaced:

resources/js/store/index.js
JS
1import state from './state'
2import actions from './actions'
3import getters from './getters'
4import mutations from './mutations'
5
6export default {
7 namespaced: true,
8 state,
9 actions,
10 getters,
11 mutations
12}

Then the tool registers it when its component is created:

resources/js/components/Tool.vue
VUE
1<template>
2 <div>
3 <heading class="mb-6">Your Tool</heading>
4
5 <card class="p-6">
6 <p v-if="loading">Loading…</p>
7 <p v-else>{{ itemCount }} items</p>
8 </card>
9 </div>
10</template>
11
12<script>
13import { mapActions, mapGetters, mapState } from 'vuex'
14import store from '../store'
15
16export default {
17 created () {
18 // The component is created again on every visit, but the store lives on.
19 if (!this.$store.state.yourTool) {
20 this.$store.registerModule('yourTool', store)
21 }
22 },
23
24 computed: {
25 ...mapState('yourTool', ['loading']),
26 ...mapGetters('yourTool', ['itemCount'])
27 },
28
29 methods: {
30 ...mapActions('yourTool', ['fetchItems'])
31 },
32
33 mounted () {
34 this.fetchItems()
35 }
36}
37</script>

The check in created() matters. Nova keeps the same root instance, and with it the same store, while you navigate, but your tool’s component is created again each time you open the tool. Registering the module again would replace it and throw away its state, so register it only when its state isn’t there yet.

Since the module stays registered, the tool’s state also survives leaving the tool and coming back, which is usually what you want for filters or a half-filled form.

Why it’s future proof

This is a future proof method because the team probably won’t remove Vuex support in the future, and this is a supported, although little known, way of adding modules to the Vuex store.

It’s recommended that you namespace your modules to avoid collisions with other libraries!

TAGS
Laravel
Nova
Vue
Vuex
06 · CONTACT

Have a system that needs building?

GET IN TOUCH → PROJECTS →
PRODUCT DATA SHEET
MG—01
BLACKFYRE
S/N MG-1985-1027
Miklós Galicz — Golang Advocate · Solution Architect
MODEL
MG—01 "Miklós Galicz"
SERIES
1985
ORIGIN
Nagykovácsi, Hungary
FUNCTION
Senior Full Stack Engineer · Solution Architect
CORE LANGUAGES
Go · PHP · JavaScript
SPOKEN
Hungarian · English · German
SERVICE LIFE
~20 years in software, ongoing
POWER SUPPLY
Coffee, 2–4 cups / day
DIMENSIONS
1 × human, standard size
OPERATING TEMP.
Calm under production incidents
CONNECTIVITY
[email protected] · github.com/blackfyre · linkedin.com/in/galiczmiklos
Less, but better. Specifications subject to continuous improvement.
● ● ●
MG—01 · SERIES 1985
№ MG-1985-1027
CERTIFICATE OF OPERATION
Certified Operator
Has located every documented feature of the MG—01 without reading the manual. Probably.
TIME
—
FEATURES
—
DATE
—
SIGNED
Miklós Galicz