Releases: feathersjs-ecosystem/feathers-vuex
Remove straggling stories.js file in `dist` folder
Just what it says on the label.
Prevent stories from getting copied to `dist` folder.
The TypeScript compiler was still copying the stories from src
to dist
, which interferes with project Storybook configurations. To keep project config simple, the stories are now moved into the ./stories
folder. This will keep them from getting copied to dist
.
Add src/*.stories.js to `.npmignore`
This prevents Storybook stories in the src
folder from getting published to npm.
🎁 Adds the `FeathersVuexInputWrapper`
This release adds the new, renderless FeathersVuexInputWrapper
component which makes quick work of "edit-in-place" inputs:
<template>
<div class="p-3">
<FeathersVuexInputWrapper :item="user" prop="email">
<template #default="{ current, prop, createClone, handler }">
<input v-model="current[prop]" type="text" @focus="createClone" @blur="e => handler(e, save)" />
</template>
</FeathersVuexInputWrapper>
<!-- Simple readout to show that it's working. -->
<pre class="bg-black text-white text-xs mt-2 p-1">{{user}}</pre>
</div>
</template>
<script>
export default {
name: 'InputWrapperExample',
props: {
user: {
type: Object,
required: true
}
},
methods: {
// Optionally make the event handler async.
async save({ event, clone, prop, data }) {
const user = clone.commit()
return user.patch(data)
}
}
}
</script>
Improve `makeFindMixin` usability & efficiency when `local` option is used.
The makeFindMixin
now allows using the mixed-in find${Resources}
utility (e.g. findTodos
for a todos
service) when the local
option is provided. It also updates the mixin so that the watchers are not created when using the local
option, since the watchers only function is to re-run the API query when something changes. This change will avoid some useless processing that was occurring in local
mode.
🎁 Hydration API for Nuxt, FeathersVuexGet supports params
New APIs are available which allow for hydrating data in the Nuxt client. See https://vuex.feathersjs.com/nuxt.html#server-side-hydration
FeathersVuexGet now supports params
and fetchParams
props, which allows passing custom params to the server using hooks like paramsForServer
and paramsFromClient
.
🐜 Fixes the equality check for the event handlers
This fixes a mistake that was made checking for removed
in the event handlers. It was using the assignment operator =
instead of the equality operator ===
.
🎁 Add `user` and `isAuthenticated` getters to the Auth plugin
This addresses a problem where the user state of the auth module is no longer reactive after destructuring. To fix this issue, two getters have been added to the auth state. They are available when a userService is provided to the makeAuthPlugin options.
user
: returns the reactive, logged-in user from the userService specified in the options.isAuthenticated
: an easy to remember boolean attribute for if the user is logged in.
If you depend on a reactive, logged-in user in your apps, here is how to fix the reactivity:
Replace any reference to store.state.auth.user with store.state.getters('auth/user').
Because the user state is no longer reactive, it is logical for it to be removed in the next version. It will likely be replaced by a userId attribute in Feathers-Vuex 4.0.
For more clarity on 3.2.0, the user in state is actually reactive UNLESS you destructure.
const { user } = store.state.auth
if (user === null) {
// congrats, you just lost reactivity because it's a primitive
} else {
// the properties of the user record will be reactive.
}
As soon as null is returned (when there's no user) the reactivity is broken. Of course it works this way because a primitive can't have any reactivity on its own. The new user getter will always be reactive, whether it's null or an actual user.
const user = store.getters['auth/user']
if (user === null) {
// user itself is still reactive
} else {
// user continues to be reactive
}
Reactivity doesn't work on objects because it requires either
- the use of ES5 accessor properties (getters and setters on objects) or...
- the use of Proxy objects (like in Vue 3)
Either way, if it's not an object it can't be reactive. And I mean a real object. I thought I better clarify since typeof null === 'object', which I'm sure has to make sense for somebody.
Fix bug in the 'removed' event handler.
The event handler for removed was mistakenly calling the non-existent removeItem
action instead of the correct removeItem
mutation. This is now fixed.
🎁 Custom Handlers for FeathersJS Events
As of version 3.1, you can customize the behavior of the event handlers, or even perform side effects based on the event data. This is handled through the new handleEvents
option on the service plugin. Here is an example of how you might use this:
handleEvents: {
created: (item, { model, models }) => {
// Perform a side effect to remove any record with the same `name`
const existing = Model.findInStore({ query: { name: item.name }}).data[0]
if (existing) {
existing.remove()
}
// Perform side effects with other models.
const { SomeModel } = models.api
new SomeModel({ /* some custom data */ }).save()
// Access the store through model.store
const modelState = model.store.state[model.namespace]
if (modelState.keyedById[5]) {
console.log('we accessed the vuex store')
}
// If true, the new item will be stored.
return true
},
updated: () => false, // Ignore `updated` events.
patched: item => item.hasPatchedAttribute && item.isWorthKeeping,
removed: item => true // The default value, will remove the record from the store
}
As shown above, each handler has two possible uses:
- Control the default behavior of the event by returning a boolean.
- For
created
,patched
, andupdated
a truthy return will add or update the item in the store. - For
removed
a truthy return will remove the item from the store, if present.
- Perform side effects using the current service
model
or with othermodels
. Themodels
object is the same as the$FeathersVuex
object in the Vue plugin.
Each handler receives the following arguments:
item
: the record sent from the API serverutils
: an object containing the following propertiesmodel
The current service's Model class.models
The same as the$FeathersVuex
object, gives you access to each api with their respective model classes.