# Getting Started with Feathers-Vuex
# Installation
npm install feathers-vuex @vue/composition-api --save
yarn add feathers-vuex @vue/composition-api
IMPORTANT: Feathers-Vuex is (and requires to be) published in ES6 format for full compatibility with JS classes. If your project uses Babel, it must be configured properly. See the Project Configuration section for more information.
# With feathers-socketio
A realtime-transport like Socket.io or Primus is required in order to take advantage of the real-time socket events built into Feathers-Vuex. The feathers-hooks-common
package, specified below, is not required to work with Feathers-Vuex.
npm i @feathersjs/feathers @feathersjs/socketio-client @feathersjs/authentication-client socket.io-client @vue/composition-api feathers-vuex feathers-hooks-common --save
yarn add @feathersjs/feathers @feathersjs/socketio-client @feathersjs/authentication-client socket.io-client @vue/composition-api feathers-vuex feathers-hooks-common
# With feathers-rest
Feathers-Vuex works with Feathers-Rest, but keep in mind that the feathers-rest
client does not listen to socket events. The feathers-hooks-common
package, specified below, is not required to work with Feathers-Vuex.
npm i @feathersjs/feathers @feathersjs/rest-client @feathersjs/authentication-client @vue/composition-api feathers-hooks-common feathers-vuex --save
yarn add @feathersjs/feathers @feathersjs/rest-client @feathersjs/authentication-client @vue/composition-api feathers-hooks-common feathers-vuex
# Project Configuration
# Vue-CLI
If your project runs on Vue-CLI, add the following to your vue.config.js
file:
module.exports = {
transpileDependencies: ['feathers-vuex']
}
# Quasar
In newer Quasar apps, the following
transpileDependencies
setup may not be necessary, anymore. See this issue on GitHub (opens new window)
For Quasar apps, transpileDependencies
can be updated in quasar.conf.js
under build as
build: {
transpileDependencies: ['feathers-vuex']
}
# Nuxt
If your project uses Nuxt, add the following to your nuxt.config.js
file:
build: {
transpile: ['feathers-vuex'],
}
# Resolving Build Issues
If you have issues with sub-dependencies not loading correctly, you may want to check out this GitHub issue (opens new window). One of the suggestions is likely to fix the issue.
Be sure to read the section of the docs dedicated to Working With Nuxt.
# Vue DevTools
Since Feathers-Vuex extensively uses Vuex under the hood, you'll want to make sure your VueJS developer tools are up to date AND setup properly. Specifically, the "New Vuex Backend" needs to be enabled. To setup the devtools
- Open the Vue tab of the developer tools while viewing your Vue project in the browser.
- Go to the Settings panel.
- Enable the new Vuex backend:
When the above setting is not enabled, the Vue Devtools will likely hang when you start working on a large project.
# Setup
Using Feathers-Vuex happens in these steps:
- Setup the Feathers client and Feathers-Vuex
- Define a Model class and service plugin for each service
- Setup the auth plugin, if required.
- Register the plugins with the Vuex store.
# Feathers Client & Feathers-Vuex
To setup feathers-vuex
, we first need to setup the latest Feathers client. We can also setup feathers-vuex in the same file. Depending on your requirements, you'll need to install the feathers-client dependencies, as shown, above.
Note that this example includes an app-level hook that removes attributes for handling temporary (local-only) records.
// src/feathers-client.js
import feathers from '@feathersjs/feathers'
import socketio from '@feathersjs/socketio-client'
import auth from '@feathersjs/authentication-client'
import io from 'socket.io-client'
import { iff, discard } from 'feathers-hooks-common'
import feathersVuex from 'feathers-vuex'
const socket = io('http://localhost:3030', {transports: ['websocket']})
const feathersClient = feathers()
.configure(socketio(socket))
.configure(auth({ storage: window.localStorage }))
.hooks({
before: {
all: [
iff(
context => ['create', 'update', 'patch'].includes(context.method),
discard('__id', '__isTemp')
)
]
}
})
export default feathersClient
// Setting up feathers-vuex
const { makeServicePlugin, makeAuthPlugin, BaseModel, models, FeathersVuex } = feathersVuex(
feathersClient,
{
serverAlias: 'api', // optional for working with multiple APIs (this is the default value)
idField: '_id', // Must match the id field in your database table/collection
whitelist: ['$regex', '$options']
}
)
export { makeAuthPlugin, makeServicePlugin, BaseModel, models, FeathersVuex }
# Service Plugins
The following example creates a User class and registers it with the new makeServicePlugin
utility function. This same file is also a great place to add your service-level hooks, so they're shown, too.
// src/store/services/users.js
import feathersClient, { makeServicePlugin, BaseModel } from '../../feathers-client'
class User extends BaseModel {
constructor(data, options) {
super(data, options)
}
// Required for $FeathersVuex plugin to work after production transpile.
static modelName = 'User'
// Define default properties here
static instanceDefaults() {
return {
email: '',
password: ''
}
}
}
const servicePath = 'users'
const servicePlugin = makeServicePlugin({
Model: User,
service: feathersClient.service(servicePath),
servicePath
})
// Setup the client-side Feathers hooks.
feathersClient.service(servicePath).hooks({
before: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
after: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
error: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
}
})
export default servicePlugin
# Auth Plugin
If your application uses authentication, the Auth Plugin will probably come in handy. It's a couple of lines to setup:
// src/store/store.auth.js
import { makeAuthPlugin } from '../feathers-client'
export default makeAuthPlugin({ userService: 'users' })
Read more about the Auth Plugin.
# Vuex store
This example uses Webpack's require.context
feature. If you're not using Webpack, you'll need to manually import each module and list them in the plugins
array.
// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import { FeathersVuex } from '../feathers-client'
import auth from './store.auth'
Vue.use(Vuex)
Vue.use(FeathersVuex)
const requireModule = require.context(
// The path where the service modules live
'./services',
// Whether to look in subfolders
false,
// Only include .js files (prevents duplicate imports`)
/\.js$/
)
const servicePlugins = requireModule
.keys()
.map(modulePath => requireModule(modulePath).default)
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
plugins: [...servicePlugins, auth]
})
# Begin Using Feathers-Vuex
There are a couple of ways to use Feathers-Vuex. Version 2.0 heavily focuses on abstracting away the Vuex syntax in favor of using Model classes. The Model classes are a layer on top of the Vuex getters, mutations, and actions. You can, of course, also directly use the service plugin's getters, mutations, and actions.
There are two plugins included:
- The Service Plugin adds a Vuex store for new services.
- The Auth Plugin sets up the Vuex store for authentication / logout.
To see feathers-vuex
in a working vue-cli application, check out feathers-chat-vuex
(opens new window).
# Global Configuration
The following default options are available for configuration:
const defaultOptions = {
// only configured globally
serverAlias: 'api',
keepCopiesInStore: false,
// also configurable per service
idField: 'id',
tempIdField: '__id',
nameStyle: 'short',
debug: false,
addOnUpsert: false,
autoRemove: false,
enableEvents: true,
preferUpdate: false,
replaceItems: false,
skipRequestIfExists: false,
paramsForServer: ['$populateParams'],
whitelist: [],
handleEvents: {
created: (item, { model, models }) => options.enableEvents,
patched: (item, { model, models }) => options.enableEvents,
updated: (item, { model, models }) => options.enableEvents,
removed: (item, { model, models }) => options.enableEvents
},
}
serverAlias
- Default:api
- Models are keyed byserverAlias
. Access the$FeathersVuex
Plugin and its models in your components bythis.$FeathersVuex.api.${Model}
keepCopiesInStore
- Default:false
- Set to true to store cloned copies in the store instead of on the Model. deprecatedidField {String}
- Default:'id'
- The field in each record that will contain the idtempIdField {Boolean}
- Default:'__id'
- The field in each temporary record that contains the idnameStyle {'short'|'path'}
- Default:'short'
- Use the full service path as the Vuex module name, instead of just the last section.debug {Boolean}
- Default:false
- Enable some logging for debuggingaddOnUpsert {Boolean}
- Default:false
- Iftrue
add new records pushed by 'updated/patched' socketio events into store, instead of discarding them.autoRemove {Boolean}
- Default:false
- Iftrue
automatically remove records missing from responses (only use with feathers-rest)preferUpdate {Boolean}
- Default:false
- Iftrue
, callingmodel.save()
will do anupdate
instead of apatch
.replaceItems {Boolean}
- Default:false
- Iftrue
, updates & patches replace the record in the store. Default is false, which merges in changes.skipRequestIfExists {Boolean}
- Default:false
- For get action, iftrue
the record already exists in store, skip the remote request.paramsForServer {Array}
- Default:['$populateParams']
- Custom query operators that are ignored in the find getter, but will pass through to the server. It is preconfigured to work with the$populateParams
custom operator from feathers-graph-populate (opens new window).whitelist {Array}
- Default:[]
- Custom query operators that will be allowed in the find getter.enableEvents {Boolean}
- Default:true
- Iffalse
socket event listeners will be turned off. See the serviceshandleEvents {Object}
: For this to workenableEvents
must betrue
created {Function}
- Default:(item, { model, models }) => options.enableEvents
- handlecreated
events, return true to add to the storepatched {Function}
- Default:(item, { model, models }) => options.enableEvents
- handlecreated
events, return true to update in the storeupdated {Function}
- Default:(item, { model, models }) => options.enableEvents
- handlecreated
events, return true to update in the storeremoved {Function}
- Default:(item, { model, models }) => options.enableEvents
- handleremoved
events, return true to remove from the store
Also see the Configs per Service
# Note about feathers-reactive
Previous versions of this plugin required both RxJS and feathers-reactive
to receive realtime updates. feathers-vuex@1.0.0
has socket messaging support built in and takes advantage of Vuex reactivity, so RxJS and feathers-reactive
are no longer required or supported.
Each service module can also be individually configured.