Feedback

Using Vuex

#Creating Store

Laraform's data can be kept in sync with Vuex data in case you want to manage it globally. To see it in action, first let's create a Vuex instane and add it to Laraform and Vue:

import Vue from 'vue'
import Vuex from 'vuex'
import Laraform from '@laraform/laraform'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    forms: {
      changePassword: {}
    }
  },
  // ...
})

Laraform.store(store)

Vue.use(Laraform)

const app = new Vue({
  el: '#app',
  store
})

#Using storePath

Next, create a simple change password form with storePath defined:

<?php

namespace App\Forms;

class ChangePasswordForm extends \Laraform
{
  public $storePath = 'forms.changePassword';

  public function schema() {
    return [
      'old_password' => [
        'type' => 'password',
        'label' => 'Old password',
        'rules' => 'required'
      ],
      'new_password' => [
        'type' => 'password',
        'label' => 'New password',
        'rules' => 'required|confirmed'
      ],
      'new_password_confirmation' => [
        'type' => 'password',
        'label' => 'New password again',
        'rules' => 'required'
      ]
    ];
  }  
}

Now if you render the form you'll notice that the form's data will be kept in sync with Vuex. If you change form data it will be commited to Vuex and vice verse, if you update data in Vuex the changes will be replicated in the form.

Laraform solves this by using a laraform/LARAFORM_UPDATE_STORE mutation to commit changes while watching for changes in form data. It also watches changes in store data which is a property used to directly access Vuex state according to storePath.

#Custom Store Logic

You may decide to create your own solution to store and retrive form data with Vuex. To do this, first let's assign a frontend component to the backend form:

<?php

namespace App\Forms;

class ChangePasswordForm extends \Laraform
{
  public $component = 'change-password-form';

  public $storePath = 'forms.changePassword';

  public function schema() {
    // ...
  }  
}

Now let's create the resources/js/components/forms/ChangePasswordForm.vue component we've assigned to the backend form. Make sure you import that in your main js file. After that you can override the store computed property's default set and get method:

<script>
  export module {
    mixins: [Laraform],
    computed: {
      store: {
        get() {
          if (this.storePath === null || !this.$store) {
            return null
          }

          return _.get(this.$store.state, this.storePath)
        },
        set(value) {
          if (!this.$store) {
            return
          }

          // If store is not registered with Laraform.store()
          if (!this.$store._mutations['laraform/LARAFORM_UPDATE_STORE']) {
            _.set(this.$store.state, this.storePath, value)
          } 

          // If store is registered properly call a mutation
          else {
            this.$store.commit('laraform/LARAFORM_UPDATE_STORE', {
              path: this.storePath,
              value: value
            })
          }
        }
      }
    }
  }
</script>