Skip to content

Commit c493f68

Browse files
Merge branch 'master' into count
2 parents 0dfd6bf + d71891a commit c493f68

26 files changed

+4559
-1945
lines changed

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,8 @@
1515
"activityBar.background": "#2B3011",
1616
"titleBar.activeBackground": "#3C4418",
1717
"titleBar.activeForeground": "#FAFBF4"
18-
}
18+
},
19+
"editor.defaultFormatter": "esbenp.prettier-vscode",
20+
"prettier.arrowParens": "avoid",
21+
"javascript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": false
1922
}

docs/composition-api.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ interface UseFindOptions {
105105
fetchParams?: Params | Ref<Params>
106106
queryWhen?: Ref<Function>
107107
qid?: string
108-
lazy?: boolean
108+
immediate?: boolean
109109
}
110110
```
111111

@@ -123,7 +123,7 @@ And here's a look at each individual property:
123123
- Explicitly returning `null` will prevent an API request from being made.
124124
- `queryWhen` must be a `computed` property which returns a `boolean`. It provides a logical separation for preventing API requests *outside* of the `params`.
125125
- `qid` allows you to specify a query identifier (used in the pagination data in the store). This can also be set dynamically by returning a `qid` in the params.
126-
- `lazy`, which is `false` by default, determines if the internal `watch` should fire immediately. Set `lazy: true` and the query will not fire immediately. It will only fire on subsequent changes to the params.
126+
- `immediate`, which is `true` by default, determines if the internal `watch` should fire immediately. Set `immediate: false` and the query will not fire immediately. It will only fire on subsequent changes to the params.
127127

128128
### Returned Attributes
129129

@@ -208,7 +208,7 @@ If you have already used the `makeFindMixin`, the `useFind` composition function
208208

209209
1. `useFind` is more TypeScript friendly. Since the mixins depended on adding dynamic attribute names that wouldn't overlap, TypeScript tooling and autocomplete weren't very effective. The attributes returned from `useFind` are always consistent.
210210
1. Instead of providing a service name, you provide a service Model from the `$FeathersVuex` Vue plugin.
211-
1. The default behavior of `useFind` is to immediately query the API server. The `makeFindMixin`, by default, would wait until the watcher noticed the change. This is to match the default behavior of `watch` in the Vue Composition API. You can pass `{ lazy: true }` in the `useFind` options, which will be passed directly to the internal `watch` on the params.
211+
1. The default behavior of `useFind` is to immediately query the API server. The `makeFindMixin`, by default, would wait until the watcher noticed the change. This is to match the default behavior of `watch` in the Vue Composition API. You can pass `{ immediate: false }` in the `useFind` options, which will be passed directly to the internal `watch` on the params.
212212

213213
Note that with the Vue Options API (aka the only way to write components in Vue 2.0) the models are found in `this.$FeathersVuex`. With the Vue Composition API, this object is now at `context.root.$FeathersVuex`.
214214

@@ -268,7 +268,7 @@ interface UseGetOptions {
268268
params?: Params | Ref<Params>
269269
queryWhen?: Ref<Function>
270270
local?: boolean
271-
lazy?: boolean
271+
immediate?: boolean
272272
}
273273
```
274274
@@ -281,7 +281,7 @@ And here's a look at each individual property:
281281
- `params` is a FeathersJS Params object OR a Composition API `ref` (or `computed`, since they return a `ref` instance) which returns a Params object.
282282
- Unlike the `useFind` utility, `useGet` does not currently have built-in debouncing.
283283
- `queryWhen` must be a `computed` property which returns a `boolean`. It provides a logical separation for preventing API requests apart from `null` in the `id`.
284-
- `lazy`, which is `true` by default, determines if the internal `watch` should fire immediately. By default a single query will be performed, independent of the watchers. Set `lazy: false` and the watchers on the `id` and `params` will fire immediately (currently this will cause duplicate queries to be performed, so it's not recommended).
284+
- `immediate`, which is `true` by default, determines if the internal `watch` should fire immediately. Set `immediate: false` and the query will not fire immediately. It will only fire on subsequent changes to the `id` or `params`.
285285
286286
### Returned Attributes
287287
@@ -779,6 +779,21 @@ export default new Router({
779779

780780
Now, the `Post.vue` file only requires to have a `prop` named `id`. Vue Router will pass the params from the route as props to the component. See the [first useGet example](#useget) for a component that would work with the above route. The vue-router documentation has more information about [Passing Props to Route Components](https://router.vuejs.org/guide/essentials/passing-props.html#passing-props-to-route-components)
781781

782+
### Composing with Model types
783+
784+
Both `useGet` and `useFind` have an optional type parameter for the Model type which is used as the type for the returned item(s).
785+
786+
```ts
787+
// Destructure Model class from global models object
788+
const { User } = Vue.$FeathersVuex.api
789+
790+
// use useGet with User Model
791+
useGet<typeof User.prototype>(/* ... */)
792+
793+
// use useFind with User Model
794+
useFind<typeof User.prototype>(/* ... */)
795+
```
796+
782797
## Conventions for Development
783798

784799
### Params are Computed

docs/feathers-vuex-forms.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ export default {
458458
// Optionally make the event handler async.
459459
async save({ event, clone, prop, data }) {
460460
const user = clone.commit()
461-
return user.patch(data)
461+
return user.patch({ data })
462462
}
463463
}
464464
}
@@ -497,14 +497,14 @@ myCallback({ event, clone, prop, data }) {
497497
- `event {Event}`: the event which triggered the `handler` function in the slot scope.
498498
- `clone {clone}`: the cloned version of the `item` instance that was provided as a prop.
499499
- `prop {String}`: the name of the `prop` that is being edited (will always match the `prop` prop.)
500-
- `data {Object}`: An object containing the changes that were made to the object. Useful for calling `.patch(data)` on the original instance.
500+
- `data {Object}`: An object containing the changes that were made to the object. Useful for calling `.patch({ data })` on the original instance.
501501
502502
This callback needs to be customized to fit your business logic. You might patch the changes right away, as shown in this example callback function.
503503
504504
```js
505505
async save({ event, clone, prop, data }) {
506506
const user = clone.commit()
507-
return user.patch(data)
507+
return user.patch({ data })
508508
}
509509
```
510510
@@ -550,7 +550,7 @@ export default {
550550
// The callback can be async
551551
async save({ event, clone, prop, data }) {
552552
const user = clone.commit()
553-
return user.patch(data)
553+
return user.patch({ data })
554554
}
555555
}
556556
}
@@ -593,7 +593,7 @@ export default {
593593
// The callback can be async
594594
async save({ event, clone, prop, data }) {
595595
const user = clone.commit()
596-
return user.patch(data)
596+
return user.patch({ data })
597597
}
598598
}
599599
}
@@ -640,7 +640,7 @@ export default {
640640
// The original, non-debounced save function
641641
async function save({ event, clone, prop, data }) {
642642
const user = clone.commit()
643-
return user.patch(data)
643+
return user.patch({ data })
644644
}
645645
// The debounced wrapper around the save function
646646
const debouncedSave = _debounce(save, 100)

docs/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ const requireModule = require.context(
245245
// Whether to look in subfolders
246246
false,
247247
// Only include .js files (prevents duplicate imports`)
248-
/.js$/
248+
/\.js$/
249249
)
250250
const servicePlugins = requireModule
251251
.keys()

docs/model-classes.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,77 @@ User.instanceDefaults = function() {
5151
}
5252
```
5353

54+
### BaseModel typing
55+
56+
BaseModel typing gives helpful IDE autocomplete and errors when using Model classes.
57+
58+
Since Feathers-Vuex doesn't know what your data looks like, you will need to help define your underlying model data's interface.
59+
60+
By default, Model classes are `string` indexable with value of type `any`. This isn't super helpful...
61+
62+
```ts
63+
// Just like before, we define our class as an extension of BaseModel
64+
class User extends BaseModel { /* ... */ }
65+
66+
// Augment the User Model interface
67+
interface User {
68+
email: string
69+
password: string
70+
}
71+
```
72+
73+
Now, whenever we access a `User` model, all fields defined in the interface will be available in IDE auto-complete/intellisense along with the model methods/props.
74+
75+
If you already have a User interface defined under a different name, just define a new interface with the same name as your Model class like so
76+
77+
```ts
78+
// if our User interface already exists as UserRecord
79+
interface User extends UserRecord {}
80+
```
81+
82+
To further enhance typing, you can augment FeathersVuex types to aid development in other parts of your app. It's important to note the differences in the following example if you do or do not setup a `serverAlias`.
83+
84+
```ts
85+
// src/store/user.store.ts
86+
import { ServiceState } from 'feathers-vuex'
87+
88+
class User extends BaseModel { /* ... */ }
89+
interface User { /* ... */ }
90+
const servicePath = 'users'
91+
92+
declare module "feathers-vuex" {
93+
interface FeathersVuexStoreState {
94+
[servicePath]: ServiceState<User>
95+
}
96+
97+
// Only if you setup FeathersVuex without a serverAlias!!
98+
interface FeathersVuexGlobalModels {
99+
User: typeof User
100+
}
101+
}
102+
103+
// Only if you setup FeathersVuex with a serverAlias!!
104+
declare module "src/store" {
105+
interface MyApiModels {
106+
User: typeof User
107+
}
108+
}
109+
```
110+
111+
If you have setup a `serverAlias`, you need to add the following to `src/store/index.ts`.
112+
113+
```ts
114+
// src/store/index.ts
115+
export interface MyApiModels { /* Let each service augment this interface */ }
116+
declare module "feathers-vuex" {
117+
interface FeathersVuexGlobalModels {
118+
'my-api-name': MyApiModels
119+
}
120+
}
121+
```
122+
123+
Replace `my-api-name` with the `serverAlias` you used when setting up FeathersVuex.
124+
54125
## Model attributes
55126

56127
The following attributes are available on each model:

0 commit comments

Comments
 (0)