Convert Figma logo to code with AI

maoberlehner logovuex-map-fields

Enable two-way data binding for form fields saved in a Vuex store

1,414
85
1,414
56

Top Related Projects

28,431

🗃️ Centralized State Management for Vue.js.

13,438

🍍 Intuitive, type safe, light and flexible Store for Vue using the composition api with DevTools support

💾 Persist and rehydrate your Vuex state between page reloads.

A Vuex plugin to persist the store. (Fully Typescript enabled)

Vue / Vuex plugin providing a unified path syntax to Vuex stores

Quick Overview

The vuex-map-fields library is a Vuex plugin that provides a set of helper functions to simplify the process of mapping Vuex state fields to component data properties. It aims to reduce boilerplate code and improve the overall maintainability of Vuex-based Vue.js applications.

Pros

  • Reduced Boilerplate: The library abstracts away the repetitive task of mapping Vuex state fields to component data properties, reducing the amount of code required.
  • Improved Readability: The use of the provided helper functions makes the component code more readable and easier to understand.
  • Automatic Binding: The library automatically binds the Vuex state fields to the component data properties, eliminating the need for manual binding.
  • Flexible Configuration: The library offers various configuration options to customize the mapping process, allowing developers to adapt it to their specific needs.

Cons

  • Dependency on Vuex: The library is tightly coupled with the Vuex state management library, which may be a limitation for developers who prefer alternative state management solutions.
  • Limited Functionality: While the library provides a convenient way to map Vuex state fields, it may not offer the full range of features and functionality that some developers might require.
  • Potential Learning Curve: Developers who are new to Vuex or the vuex-map-fields library may need to invest some time in understanding how to use the provided helper functions effectively.
  • Potential Performance Overhead: Depending on the size and complexity of the Vuex store, the additional layer of abstraction provided by the library may introduce a small performance overhead.

Code Examples

Here are a few examples of how to use the vuex-map-fields library:

  1. Mapping a Single Field:
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields(['name'])
  }
}
  1. Mapping Multiple Fields:
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields(['name', 'email', 'age'])
  }
}
  1. Mapping Nested Fields:
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields(['user.name', 'user.email', 'user.age'])
  }
}
  1. Mapping Fields with Custom Getters/Setters:
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields({
      fullName: {
        get: state => `${state.firstName} ${state.lastName}`,
        set: (state, value) => {
          const [firstName, lastName] = value.split(' ');
          state.firstName = firstName;
          state.lastName = lastName;
        }
      }
    })
  }
}

Getting Started

To get started with the vuex-map-fields library, follow these steps:

  1. Install the library using npm or yarn:
npm install vuex-map-fields

or

yarn add vuex-map-fields
  1. Import the mapFields helper function and use it in your Vue.js components:
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields(['name', 'email', 'age'])
  }
}
  1. Optionally, you can configure the library by passing a options object to the mapFields function:
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields('user', ['name', 'email', 'age'], {
      prefix: 'user_'
    })
  }
}
  1. For more advanced usage, refer to the project's documentation for information on custom getters/setters, nested fields, and other features.

Competitor Comparisons

28,431

🗃️ Centralized State Management for Vue.js.

Pros of Vuex

  • Official state management solution for Vue.js, ensuring long-term support and compatibility
  • Provides a comprehensive ecosystem with plugins, devtools, and extensive documentation
  • Offers a more structured approach to state management with actions, mutations, and getters

Cons of Vuex

  • Can be verbose and require more boilerplate code for simple state management tasks
  • Steeper learning curve for beginners compared to simpler state management solutions

Code Comparison

Vuex:

export default new Vuex.Store({
  state: {
    user: { name: '', email: '' }
  },
  mutations: {
    updateUser(state, payload) {
      state.user = { ...state.user, ...payload };
    }
  }
});

vuex-map-fields:

import { getField, updateField } from 'vuex-map-fields';

export default new Vuex.Store({
  state: {
    user: { name: '', email: '' }
  },
  getters: { getField },
  mutations: { updateField }
});

Summary

Vuex is the official state management solution for Vue.js, offering a robust and structured approach to managing application state. It provides a comprehensive ecosystem and extensive documentation, making it suitable for large-scale applications. However, it can be verbose for simple use cases and has a steeper learning curve.

vuex-map-fields, on the other hand, is a lightweight plugin that simplifies two-way data binding between form inputs and Vuex state. It reduces boilerplate code and makes it easier to work with form fields in Vuex. While it doesn't provide the full feature set of Vuex, it can be a useful addition for specific form-handling scenarios within a Vuex-based application.

13,438

🍍 Intuitive, type safe, light and flexible Store for Vue using the composition api with DevTools support

Pros of Pinia

  • Simpler API and less boilerplate code
  • Built-in TypeScript support
  • Better performance due to its lightweight nature

Cons of Pinia

  • Requires Vue 3, not compatible with Vue 2 without additional plugins
  • Less mature ecosystem compared to Vuex

Code Comparison

vuex-map-fields:

import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields(['firstName', 'lastName'])
  }
}

Pinia:

import { useUserStore } from '@/stores/user'

export default {
  setup() {
    const userStore = useUserStore()
    return { ...userStore }
  }
}

Key Differences

  • vuex-map-fields is a plugin for Vuex, while Pinia is a standalone state management solution
  • Pinia uses a more modular approach with individual stores
  • vuex-map-fields focuses on mapping form fields to Vuex state, while Pinia offers a more general-purpose state management solution

Use Cases

  • vuex-map-fields: Best for Vue 2 projects using Vuex with complex forms
  • Pinia: Ideal for Vue 3 projects or those seeking a lighter, more flexible state management solution

Community and Maintenance

  • vuex-map-fields: Smaller community, less frequent updates
  • Pinia: Larger community, officially supported by the Vue.js team, more frequent updates and improvements

💾 Persist and rehydrate your Vuex state between page reloads.

Pros of vuex-persistedstate

  • Automatically persists Vuex state to localStorage or other storage mechanisms
  • Supports custom storage engines and serialization methods
  • Easy to configure with minimal setup required

Cons of vuex-persistedstate

  • Focuses solely on state persistence, not on mapping or field management
  • May introduce performance overhead for large state trees
  • Requires careful consideration of which state to persist to avoid security issues

Code Comparison

vuex-persistedstate:

import createPersistedState from 'vuex-persistedstate'

const store = new Vuex.Store({
  plugins: [createPersistedState()]
})

vuex-map-fields:

import { mapFields } from 'vuex-map-fields'

export default {
  computed: {
    ...mapFields(['firstName', 'lastName'])
  }
}

Summary

vuex-persistedstate is focused on persisting Vuex state across page reloads or app restarts, while vuex-map-fields provides utilities for mapping and managing form fields within Vuex. The former is ideal for maintaining state persistence, while the latter simplifies form handling in Vuex-based applications. vuex-persistedstate requires minimal setup but may impact performance with large states, whereas vuex-map-fields offers more granular control over field mapping but doesn't address persistence concerns.

A Vuex plugin to persist the store. (Fully Typescript enabled)

Pros of vuex-persist

  • Automatically persists Vuex state to localStorage or other storage mechanisms
  • Supports custom storage engines and serialization methods
  • Allows selective persistence of specific parts of the state

Cons of vuex-persist

  • Adds complexity to the Vuex setup process
  • May impact performance if persisting large amounts of data
  • Requires additional configuration for more advanced use cases

Code Comparison

vuex-persist:

import VuexPersistence from 'vuex-persist'

const vuexLocal = new VuexPersistence({
  storage: window.localStorage
})

export default new Vuex.Store({
  plugins: [vuexLocal.plugin]
})

vuex-map-fields:

import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields(['firstName', 'lastName'])
  }
}

vuex-persist focuses on state persistence, while vuex-map-fields simplifies mapping of Vuex state to component properties. vuex-persist requires plugin setup in the Vuex store, whereas vuex-map-fields is used within components to map fields. The choice between these libraries depends on the specific needs of your application, such as state persistence or simplified state mapping.

Vue / Vuex plugin providing a unified path syntax to Vuex stores

Pros of Pathify

  • More comprehensive solution, offering a complete state management system
  • Provides automatic two-way data binding between state and components
  • Supports dynamic store modules and nested state structures

Cons of Pathify

  • Steeper learning curve due to its more complex API and features
  • May introduce additional overhead for smaller projects
  • Less focused on specific mapping functionality compared to vuex-map-fields

Code Comparison

vuex-map-fields:

import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields(['firstName', 'lastName'])
  }
}

Pathify:

import { sync } from 'vuex-pathify'

export default {
  computed: {
    ...sync('user', ['firstName', 'lastName'])
  }
}

Both libraries aim to simplify Vuex state management, but Pathify offers a more comprehensive solution with additional features like automatic two-way data binding and support for nested state structures. However, this comes at the cost of increased complexity and potential overhead.

vuex-map-fields focuses specifically on mapping state fields to component properties, making it simpler and more lightweight for projects that only need this functionality. Pathify, on the other hand, provides a complete state management system that may be beneficial for larger, more complex applications.

The code comparison shows that both libraries offer similar syntax for mapping state fields to component properties, with Pathify requiring an additional parameter to specify the store module.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

vuex-map-fields

Patreon Donate Build Status Coverage Status GitHub stars

Enable two-way data binding for form fields saved in a Vuex store.

ko-fi

Install

npm install --save vuex-map-fields

Basic example

The following example component shows the most basic usage, for mapping fields to the Vuex store using two-way data binding with v-model, without directly modifying the store itself, but using getter and setter functions internally (as it is described in the official Vuex documentation: Two-way Computed Property).

Store

import Vue from 'vue';
import Vuex from 'vuex';

// Import the `getField` getter and the `updateField`
// mutation function from the `vuex-map-fields` module.
import { getField, updateField } from 'vuex-map-fields';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    fieldA: '',
    fieldB: '',
  },
  getters: {
    // Add the `getField` getter to the
    // `getters` of your Vuex store instance.
    getField,
  },
  mutations: {
    // Add the `updateField` mutation to the
    // `mutations` of your Vuex store instance.
    updateField,
  },
});

Component

<template>
  <div id="app">
    <input v-model="fieldA">
    <input v-model="fieldB">
  </div>
</template>

<script>
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    // The `mapFields` function takes an array of
    // field names and generates corresponding
    // computed properties with getter and setter
    // functions for accessing the Vuex store.
    ...mapFields([
      'fieldA',
      'fieldB',
    ]),
  },
};
</script>

Edit basic example

Nested properties

Oftentimes you want to have nested properties in the Vuex store. vuex-map-fields supports nested data structures by utilizing the object dot string notation.

Store

import Vue from 'vue';
import Vuex from 'vuex';

import { getField, updateField } from 'vuex-map-fields';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    user: {
      firstName: '',
      lastName: '',
    },
    addresses: [
      {
        town: '',
      },
    ],
  },
  getters: {
    getField,
  },
  mutations: {
    updateField,
  },
});

Component

<template>
  <div id="app">
    <input v-model="firstName">
    <input v-model="lastName">
    <input v-model="town">
  </div>
</template>

<script>
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    // When using nested data structures, the string
    // after the last dot (e.g. `firstName`) is used
    // for defining the name of the computed property.
    ...mapFields([
      'user.firstName',
      'user.lastName',
      // It's also possible to access
      // nested properties in arrays.
      'addresses[0].town',
    ]),
  },
};
</script>

Edit nested properties example

Rename properties

Sometimes you might want to give your computed properties different names than what you're using in the Vuex store. Renaming properties is made possible by passing an object of fields to the mapFields function instead of an array.

<template>
  <div id="app">
    <input v-model="userFirstName">
    <input v-model="userLastName">
  </div>
</template>

<script>
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapFields({
      userFirstName: 'user.firstName',
      userLastName: 'user.lastName',
    }),
  },
};
</script>

Edit rename properties example

Custom getters and mutations

By default vuex-map-fields is searching for the given properties starting from the root of your state object. Depending on the size of your application, the state object might become quite big and therefore updating the state starting from the root might become a performance issue. To circumvent such problems, it is possible to create a custom mapFields() function which is configured to access custom mutation and getter functions which don't start from the root of the state object but are accessing a specific point of the state.

Store

import Vue from 'vue';
import Vuex from 'vuex';

import { getField, updateField } from 'vuex-map-fields';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    user: {
      firstName: '',
      lastName: '',
    },
  },
  getters: {
    // By wrapping the `getField()` function we're
    // able to provide a specific property of the state.
    getUserField(state) {
      return getField(state.user);
    },
  },
  mutations: {
    // Mutating only a specific property of the state
    // can be significantly faster than mutating the
    // whole state every time a field is updated.
    updateUserField(state, field) {
      updateField(state.user, field);
    },
  },
});

Component

<template>
  <div id="app">
    <input v-model="firstName">
    <input v-model="lastName">
  </div>
</template>

<script>
import { createHelpers } from 'vuex-map-fields';

// The getter and mutation types we're providing
// here, must be the same as the function names we've
// used in the store.
const { mapFields } = createHelpers({
  getterType: 'getUserField',
  mutationType: 'updateUserField',
});

export default {
  computed: {
    // Because we're providing the `state.user` property
    // to the getter and mutation functions, we must not
    // use the `user.` prefix when mapping the fields.
    ...mapFields([
      'firstName',
      'lastName',
    ]),
  },
};
</script>

Edit custom getters and mutations example

Vuex modules

Vuex makes it possible to divide the store into modules.

Store

import Vue from 'vue';
import Vuex from 'vuex';

import { createHelpers } from 'vuex-map-fields';

// Because by default, getters and mutations in Vuex
// modules, are globally accessible and not namespaced,
// you most likely want to rename the getter and mutation
// helpers because otherwise you can't reuse them in multiple,
// non namespaced modules.
const { getFooField, updateFooField } = createHelpers({
  getterType: 'getFooField',
  mutationType: 'updateFooField',
});

Vue.use(Vuex);

export default new Vuex.Store({
  // ...
  modules: {
    fooModule: {
      state: {
        foo: '',
      },
      getters: {
        getFooField,
      },
      mutations: {
        updateFooField,
      },
    },
  },
});

Component

<template>
  <div id="app">
    <input v-model="foo">
  </div>
</template>

<script>
import { createHelpers } from 'vuex-map-fields';

// We're using the same getter and mutation types
// as we've used in the store above.
const { mapFields } = createHelpers({
  getterType: 'getFooField',
  mutationType: 'updateFooField',
});

export default {
  computed: {
    ...mapFields(['foo']),
  },
};
</script>

Edit Vuex modules example

Namespaced Vuex modules

By default, mutations and getters inside modules are registered under the global namespace – but you can mark modules as namespaced which prevents naming clashes of mutations and getters between modules.

Store

import Vue from 'vue';
import Vuex from 'vuex';

import { getField, updateField } from 'vuex-map-fields';

Vue.use(Vuex);

export default new Vuex.Store({
  // ...
  modules: {
    fooModule: {
      namespaced: true,
      state: {
        foo: '',
      },
      getters: {
        getField,
      },
      mutations: {
        updateField,
      },
    },
  },
});

Component

<template>
  <div id="app">
    <input v-model="foo">
  </div>
</template>

<script>
import { createHelpers } from 'vuex-map-fields';

// `fooModule` is the name of the Vuex module.
const { mapFields } = createHelpers({
  getterType: 'fooModule/getField',
  mutationType: 'fooModule/updateField',
});

export default {
  computed: {
    ...mapFields(['foo']),
  },
};
</script>

Edit namespaced Vuex modules example

Or you can pass the module namespace string as the first argument of the mapFields() function.

<template>
  <div id="app">
    <input v-model="foo">
  </div>
</template>

<script>
import { mapFields } from 'vuex-map-fields';

export default {
  computed: {
    // `fooModule` is the name of the Vuex module.
    ...mapFields('fooModule', ['foo']),
  },
};
</script>

Edit namespaced Vuex modules example

Multi-row fields

If you want to build a form which allows the user to enter multiple rows of a specific data type with multiple fields (e.g. multiple addresses) you can use the multi-row field mapping function.

Store

import Vue from 'vue';
import Vuex from 'vuex';

import { getField, updateField } from 'vuex-map-fields';

Vue.use(Vuex);

export default new Vuex.Store({
  // ...
  state: {
    addresses: [
      {
        zip: '12345',
        town: 'Foo Town',
      },
      {
        zip: '54321',
        town: 'Bar Town',
      },
    ],
  },
  getters: {
    getField,
  },
  mutations: {
    updateField,
  },
});

Component

<template>
  <div id="app">
    <div v-for="address in addresses">
      <label>ZIP <input v-model="address.zip"></label>
      <label>Town <input v-model="address.town"></label>
    </div>
  </div>
</template>

<script>
import { mapMultiRowFields } from 'vuex-map-fields';

export default {
  computed: {
    ...mapMultiRowFields(['addresses']),
  },
};
</script>

Edit multi-row fields example

Upgrade from 0.x.x to 1.x.x

Instead of accessing the state directly, since the 1.0.0 release, in order to enable the ability to implement custom getters and mutations, vuex-map-fields is using a getter function to access the state. This makes it necessary to add a getter function to your Vuex store.

import Vue from 'vue';
import Vuex from 'vuex';

// You now have to also import the `getField()` function.
import { getField, updateField } from 'vuex-map-fields';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    fieldA: '',
    fieldB: '',
  },
  getters: {
    // Add the `getField` getter to the
    // `getters` of your Vuex store instance.
    getField,
  },
  mutations: {
    updateField,
  },
});

Patreon Sponsors

Spiffy

Become a sponsor and get your logo in this README with a link to your site.

Articles

About

Author

Markus Oberlehner
Website: https://markus.oberlehner.net
Twitter: https://twitter.com/MaOberlehner
PayPal.me: https://paypal.me/maoberlehner
Patreon: https://www.patreon.com/maoberlehner

License

MIT

NPM DownloadsLast 30 Days