Skip to content

Commit fa7b1f8

Browse files
Merge pull request #388 from feathersjs-ecosystem/3.0
Feathers-Vuex 3.0
2 parents a879560 + 0d33e98 commit fa7b1f8

26 files changed

+1752
-393
lines changed

docs/.vuepress/config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@ module.exports = {
99
editLinks: true,
1010
sidebar: [
1111
'/api-overview.md',
12+
'/3.0-major-release.md',
1213
'/vue-plugin.md',
1314
'/service-plugin.md',
1415
'/auth-plugin.md',
1516
'/model-classes.md',
1617
'/common-patterns.md',
18+
'/composition-api.md',
1719
'/mixins.md',
1820
'/data-components.md',
1921
'/feathers-vuex-form-wrapper.md',
2022
'/nuxt.md',
21-
'/2.0-major-release.md'
23+
'/2.0-major-release.md',
2224
],
2325
serviceWorker: {
2426
updatePopup: true

docs/2.0-major-release.md

Lines changed: 19 additions & 206 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
title: 2.0 Breaking Changes
3+
sidebarDepth: 3
4+
---
5+
16
# 2.0 Breaking Changes
27

38
The biggest change in Feathers-Vuex 2.0 is that it has been refactored with TypeScript! (It's mostly ES6, still)
@@ -104,189 +109,7 @@ const store = new Vuex.Store({
104109
})
105110
```
106111

107-
## Setting up a project
108-
109-
There are four steps to setting up the entirety of `feathers-vuex`:
110-
111-
1. Setup the FeathersJS Client.
112-
2. Setup each Service plugin
113-
3. Setup the Auth plugin
114-
4. Register all plugins with Vuex
115-
116-
### Setup the FeathersJS Client
117-
118-
It's now recommended that the FeathersJS and client live together in the same file. This cleans up imports when setting up services. So let's start with the `feathers-client.js` file. I usually put this in `src/feathers-client.js`, but you can put it in the store folder if you want.
119-
120-
```js
121-
// src/feathers-client.js
122-
import feathers from '@feathersjs/feathers'
123-
import socketio from '@feathersjs/socketio-client'
124-
import authClient from '@feathersjs/authentication-client'
125-
import io from 'socket.io-client'
126-
import feathersVuex from 'feathers-vuex' // or '@/libs/feathers-vuex' if you're copying feathers-vuex as mentioned earlier.
127-
128-
// Setup the Feathers client
129-
const host = process.env.VUE_APP_API_URL // or set a string here, directly
130-
const socket = io(host, { transports: ['websocket'] })
131-
const feathersClient = feathers()
132-
.configure(socketio(socket))
133-
.configure(authClient({ storage: window.localStorage }))
134-
135-
export default feathersClient
136-
137-
// Setup feathers-vuex
138-
const {
139-
makeServicePlugin,
140-
makeAuthPlugin,
141-
BaseModel,
142-
models,
143-
clients,
144-
FeathersVuex
145-
} = feathersVuex(feathersClient, {
146-
serverAlias: 'api', // or whatever that makes sense for your project
147-
idField: '_id' // `id` and `_id` are both supported, so this is only necessary if you're using something else.
148-
})
149-
150-
export {
151-
makeAuthPlugin,
152-
makeServicePlugin,
153-
BaseModel,
154-
models,
155-
clients,
156-
FeathersVuex
157-
}
158-
159-
```
160-
161-
Now that we have setup the client, we can use the configured exports in each of our services.
162-
163-
### Setup the Services Plugins
164-
165-
Now let's setup a Vuex plugin for each service. I use Webpack's `require.context` to automatically import all of the services instead of explicitly typing them all. So, I'll put the services in the `src/store/services` folder.
166-
167-
```js
168-
// Bring in the imports from the feathers-client.js file.
169-
import feathersClient, {
170-
makeServicePlugin,
171-
BaseModel
172-
} from '../../feathers-client'
173-
174-
// Extend the base class
175-
class User extends BaseModel {
176-
constructor(data, options) {
177-
super(data, options)
178-
}
179-
static modelName = 'User'
180-
static instanceDefaults() {
181-
return {
182-
firstName: '',
183-
lastName: '',
184-
email: '',
185-
password: ''
186-
}
187-
}
188-
get fullName() {
189-
return `${this.firstName} ${this.lastName}`
190-
}
191-
}
192-
const servicePath = 'users'
193-
const servicePlugin = makeServicePlugin({
194-
Model: User,
195-
service: feathersClient.service(servicePath),
196-
servicePath
197-
})
198-
199-
// Optionally add service-level hooks, here:
200-
feathersClient.service(servicePath).hooks({
201-
before: {
202-
all: [],
203-
find: [],
204-
get: [],
205-
create: [],
206-
update: [],
207-
patch: [],
208-
remove: []
209-
},
210-
after: {
211-
all: [],
212-
find: [],
213-
get: [],
214-
create: [],
215-
update: [],
216-
patch: [],
217-
remove: []
218-
},
219-
error: {
220-
all: [],
221-
find: [],
222-
get: [],
223-
create: [],
224-
update: [],
225-
patch: [],
226-
remove: []
227-
}
228-
})
229-
230-
export default servicePlugin
231-
232-
```
233-
234-
Once the service plugin is exported, we can register it with Vuex, but first let's setup the auth plugin.
235-
236-
### Setup the Auth Plugin
237-
238-
We'll use the `makeAuthPlugin` method to tell the auth plugin where to find our `/users` service:
239-
240-
```js
241-
// src/store/store.auth.js
242-
import feathersClient, { makeAuthPlugin } from '../feathers-client'
243-
244-
export default makeAuthPlugin({ userService: 'users' })
245-
246-
```
247-
248-
Once you've added the export, we're finally ready to setup the store.
249-
250-
### Register all plugins with Vuex
251-
252-
The final step is to add all of the plugins to the Vuex store.
253-
254-
```js
255-
// src/store/store.js
256-
import Vue from 'vue'
257-
import Vuex from 'vuex'
258-
import { FeathersVuex } from 'feathers-vuex'
259-
import auth from './store.auth'
260-
261-
Vue.use(Vuex)
262-
Vue.use(FeathersVuex)
263-
264-
// Require the entire folder of service plugins with Webpack
265-
const requireModule = require.context( './services', false, /.js$/ )
266-
const servicePlugins = requireModule
267-
.keys()
268-
.map(modulePath => requireModule(modulePath).default)
269-
270-
// Or you can import them manually for Rollup, etc.
271-
import users from './services/users'
272-
273-
export default new Vuex.Store({
274-
state: {},
275-
getters: {},
276-
mutations: {},
277-
actions: {},
278-
plugins: [
279-
...servicePlugins, // if you're using require.context, spread the plugins into the array.
280-
users, // if you're manually importing, just add the plugins into the array, like this
281-
auth
282-
]
283-
})
284-
285-
```
286-
287-
With the above four steps accomplished, the base of most any application using `feathers-vuex` is ready to build something awesome!
288-
289-
## FeathersVuex Vue plugin changes
112+
## Feathers-Vuex Vue plugin changes
290113

291114
The Vue plugin is registered in exactly the same way. The difference comes when you try to find the Model classes in the `$FeathersVuex` object. Instead of finding models directly on the `$FeathersVuex` object, they are namespaced by the `serverAlias` you provided. This allows cleaner support for multiple APIs. Supposing you had this code in a component, previously...
292115

@@ -320,7 +143,7 @@ Because of the new ability to handle temporary records, a message is only logged
320143

321144
## Getters Work with Temporary Records
322145

323-
The `find` getter has been updated to include records from `state.tempsById`, by default. You can pass `temps: false` in the params to only search `state.keyedById`: `find({ query: {}, temps: false })`
146+
The `find` getter has been updated to include records from `state.tempsById` when you pass `temps: true` in the params.
324147

325148
The `get` getter has also been updated to work with temp ids. Pass the tempId the way you normally would pass the id: `get(tempId)`
326149

@@ -804,21 +627,21 @@ The above code will override the `responseHandler` auth action to work with the
804627
805628
Don't try to perform a query from within a getter like the example, below. It will result in an infinite loop:
806629
807-
```
630+
```js
808631
get user () {
809-
if (this.userId) {
810-
const user = Models.User.getFromStore(this.userId)
632+
if (this.userId) {
633+
const user = Models.User.getFromStore(this.userId)
811634

812-
// Fetch the User record if we don't already have it
813-
if (!user) {
814-
Models.User.get(this.userId)
815-
}
635+
// Fetch the User record if we don't already have it
636+
if (!user) {
637+
Models.User.get(this.userId)
638+
}
816639

817-
return user
818-
} else {
819-
return null
820-
}
821-
}
640+
return user
641+
} else {
642+
return null
643+
}
644+
}
822645
```
823646
824647
### Using custom query parameters
@@ -829,13 +652,3 @@ There are two places where the query operators have to be allowed.
829652
- Inside feathers-vuex (for the getters): Check out the `paramsForServer` and `whitelist` options for `feathers-vuex`. Both accept an array of strings representing prop names, but now I can't remember why I determined that I needed both. :)
830653
831654
For the Feathers Client, follow the FeathersJS docs for your database adapter.
832-
833-
### Access `$FeathersVuex` models in Nuxt `asyncData`
834-
835-
In `feathers-vuex@2.x`, you can get access to the `$FeathersVuex` object by importing the `models` object from the main export:
836-
837-
```
838-
import { models } from 'feathers-vuex'
839-
```
840-
841-
`models` and `$FeathersVuex` are the same object.

docs/3.0-major-release.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
title: What's New in 3.0
3+
sidebarDepth: 3
4+
---
5+
6+
# What's new in Feathers-Vuex 3.0
7+
8+
## Vue Composition API Support
9+
10+
Version 3.0 of Feathers-Vuex is the Vue Composition API release! There were quite a few disappointed (and misinformed:) developers in 2019 when the Vue.js team announced what is now called the Vue Composition API. From my perspective:
11+
12+
- It is the most powerful feature added to Vue since its first release.
13+
- It improves the ability to create dynamic functionality in components.
14+
- It greatly enhances organization of code in components.
15+
- It encourages code re-use. Check out the [vue-use-web](https://logaretm.github.io/vue-use-web/) collection for some great examples.
16+
17+
And now it has become the best way to perform queries with Feathers-Vuex. To find out how to take advantage of the new functionality in your apps, read the [Feather-Vuex Composition API docs](./composition-api.md).
18+
19+
## A Single Breaking Change
20+
21+
Since Feathers-Vuex follows semantic versioning, a single, small breaking change is the reason for the major version bump. Feathers-Vuex 3.0 has only one breaking change:
22+
23+
The `makeFindMixin` (and the new `useFind` utility) now have server-side pagination support turned off, by default. Real-time arrays of results are now the default setting. This really improves the development experience, especially for new users.
24+
25+
To migrate your app to version 3.0, you need to update any `params` where you are using server-side pagination. It will work as it has been in version 2.0 once you explicitly set `paginate: true` in the params, like this:
26+
27+
```js
28+
import { makeFindMixin } from 'feathers-vuex'
29+
30+
export default {
31+
name: 'MyComponent',
32+
mixins: [ makeFindMixin({ service: 'users', watch: true })],
33+
computed: {
34+
usersParams() {
35+
return {
36+
query: {},
37+
paginate: true // explicitly enable pagination, now.
38+
}
39+
}
40+
}
41+
}
42+
```
43+
44+
That's the only breaking change in this release. This behavior exactly matches the new `useFind` utility.
45+
46+
## One Deprecation
47+
48+
The `keepCopiesInStore` option is now deprecated. This was a part of the "clone and commit" API which basically disabled the reason for creating the "clone and commit" API in the first place.
49+
50+
If you're not familiar with the Feathers-Vuex "clone and commit" API, you can learn more about the [built-in data modeling](./model-classes.md) API and the section about [Working with Forms](./feathers-vuex-form-wrapper.md#the-clone-and-commit-pattern).
51+
52+
The `keepCopiesInStore` feature is set to be removed in Feathers-Vuex 4.0.

docs/api-overview.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ These docs are for version 2.x. For [email protected], please go to [https://fe
3838
- [Renderless Data Components](./data-components.md)
3939
- [Renderless Form Component](./feathers-vuex-form-wrapper.md#feathersvuexformwrapper) for Simplified Vuex Forms
4040
- [Temporary (Local-only) Record Support](./2.0-major-release.md#support-for-temporary-records) *
41+
- New `useFind` and `useGet` Vue Composition API super powers! <Badge text="3.0.0+" />
4142
- [Server-Powered Pagination Support](./service-plugin.md#pagination-and-the-find-action) *
4243
- [VuePress Dark Mode Support](https://tolking.github.io/vuepress-theme-default-prefers-color-scheme/) for the Docs
4344

44-
`* Improved in v2.0.0`<br />
45-
`** New in v2.0.0`
45+
`** Improved in v3.0.0`
4646

4747
## Installation
4848

@@ -112,6 +112,8 @@ build: {
112112
}
113113
```
114114

115+
Be sure to read the section of the docs dedicated to [Working With Nuxt](./nuxt.md).
116+
115117
## Vue DevTools
116118

117119
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
@@ -185,7 +187,7 @@ The following example creates a User class and registers it with the new `makeSe
185187

186188
```js
187189
// src/store/services/users.js
188-
import feathersClient, { makeServicePlugin, BaseModel } from '../feathers-client'
190+
import feathersClient, { makeServicePlugin, BaseModel } from '../../feathers-client'
189191

190192
class User extends BaseModel {
191193
constructor(data, options) {

0 commit comments

Comments
 (0)