You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/feathers-vuex-forms.md
+190-7Lines changed: 190 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,7 @@ sidebarDepth: 4
5
5
6
6
# Working with Forms
7
7
8
-
The `FeathersVuexFormWrapper`is a renderless component which assists in connecting your feathers-vuex data to a form. The next two sections review why it exists by looking at a couple of common patterns. Proceed to the [FeathersVuexFormWrapper](#feathersvuexformwrapper)section to learn how to implement.
8
+
The `FeathersVuexFormWrapper`and `FeathersVuexInputWrapper` are renderless components which assist in connecting your feathers-vuex data to a form. The next two sections review why they exist by looking at a couple of common patterns. Proceed to the [FeathersVuexFormWrapper](#feathersvuexformwrapper)or [FeathersVuexInputWrapper](#feathersvuexinputwrapper) sections to learn how to implement.
9
9
10
10
## The Mutation Multiplicity (anti) Pattern
11
11
@@ -151,7 +151,7 @@ The default slot contains only four attributes. The `clone` data can be passed
151
151
- `reset`: {Function} When called, the clone data will be reset back to the data that is currently found in the store for the same record.
152
152
- `remove`: {Function} When called, it removes the record from the API server and the Vuex store.
153
153
154
-
## Example Usage: CRUD Form
154
+
## FormWrapper Example: CRUD Form
155
155
156
156
### TodoView
157
157
@@ -277,7 +277,11 @@ export default {
277
277
278
278
## FeathersVuexInputWrapper
279
279
280
-
Building on the same ideas as the FeathersVuexFormWrapper, the FeathersVuexInputWrapper reduces boilerplate for working with the clone and commit pattern on a single input. One use case for this component is implementing an "edit-in-place" workflow. The following example shows how to use the FeathersVuexInputWrapper to automatically save a record upon `blur` on text and color inputs:
280
+
Building on the same ideas as the FeathersVuexFormWrapper, the FeathersVuexInputWrapper reduces boilerplate for working with the clone and commit pattern on a single input.
281
+
282
+
An important difference with the FeathersVuexInputWrapper is that it is built using the Vue Composition API. This means that in order to use it you will need to install and use the `@vue/composition-api` package in your Vue project, [as described here](/composition-api.html).
283
+
284
+
One use case for this component is implementing an "edit-in-place" workflow. The following example shows how to use the FeathersVuexInputWrapper to automatically save a record upon `blur` on text and color inputs:
281
285
282
286
```html
283
287
<template>
@@ -288,9 +292,89 @@ Building on the same ideas as the FeathersVuexFormWrapper, the FeathersVuexInput
Notice that in the `save` handler in the above example, the `.patch` method is called on the user, passing in the data. Because the data contains only the user property which changed, the patch request will only send the data which has changed, saving precious bandwidth.
315
+
316
+
### Props
317
+
318
+
The `FeathersVuexInputWrapper` has two props, both of which are required:
319
+
320
+
- `item`: The original (non-cloned) model instance.
321
+
- `prop`: The property name on the model instance to be edited.
322
+
323
+
### Default Slot Scope
324
+
325
+
Only the default slot is used. The following props are available in the slot scope:
326
+
327
+
- `current {clone|instance}`: returns the clone if it exists, or the original record. `current = clone || item`
328
+
- `clone { clone }`: the internal clone. This is exposed for debugging purposes.
329
+
- `prop {String}`: the value of the `prop` prop. If you have the prop stored in a variable in the outer scope, this is redundant and not needed. You could just use this from the outer scope. It mostly comes in handy when you are manually specifying the `prop` name on the component.
330
+
- `createClone {Function}`: sets up the internal clone. Meant to be used as an event handler.
331
+
- `handler {Function}`: has the signature `handler(event, callback)`. It prepared data before calling the callback function that must be provided from the outer scope.
332
+
333
+
### The Callback Function
334
+
335
+
The `handler` function in the slot scope requires the use of a callback function as its second argument. Here's an example callback function followed by an explanation of its properties:
336
+
337
+
```js
338
+
myCallback({ event, clone, prop, data }) {
339
+
clone.commit()
340
+
}
341
+
```
342
+
343
+
- `event {Event}`: the event which triggered the `handler` function in the slot scope.
344
+
- `clone {clone}`: the cloned version of the `item` instance that was provided as a prop.
345
+
- `prop {String}`: the name of the `prop` that is being edited (will always match the `prop` prop.)
346
+
- `data {Object}`: An object containing the changes that were made to the object. Useful for calling `.patch(data)` on the original instance.
347
+
348
+
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.
349
+
350
+
```js
351
+
asyncsave({ event, clone, prop, data }) {
352
+
constuser=clone.commit()
353
+
returnuser.patch(data)
354
+
}
355
+
```
356
+
357
+
Notice in the example above that the `save` function is `async`. This means that it returns a promise, which in this case is the `user.patch` request. Internally, the `handler` method will automatically set the internal `clone` object to `null`, which will cause the `current` computed property to return the original instance.
358
+
359
+
Note that some types of HTML input elements will call `handler` repeatedly, so the handler needs to be debounced. See an example, below.
360
+
361
+
## InputWrapper Examples
362
+
363
+
### Text Input
364
+
365
+
With a text input, you can use the `focus` and `blur` events
@@ -302,8 +386,14 @@ Building on the same ideas as the FeathersVuexFormWrapper, the FeathersVuexInput
302
386
<script>
303
387
export default {
304
388
name: 'InputWrapperExample',
389
+
props: {
390
+
user: {
391
+
type: Object,
392
+
required: true
393
+
}
394
+
},
305
395
methods: {
306
-
//Optionally make the event handler async.
396
+
// The callback can be async
307
397
async save({ event, clone, prop, data }) {
308
398
const user = clone.commit()
309
399
return user.patch(data)
@@ -313,4 +403,97 @@ export default {
313
403
</script>
314
404
```
315
405
316
-
Notice that in the `save` handler in the above example, the `.patch` method is called on the user, passing in the data. Because the data contains only the user property which changed, the patch request will only send the data which has changed, saving precious bandwidth.
406
+
### Color Input
407
+
408
+
Here is an example of using the FeathersVuexInputWrapper on a color input. Color inputs emit a lot of `input` and `change` events, so you'll probably want to debounce the callback function if you are going to immediately save changes. The example after this one shows how you might debounce.
Here is an example of using the FeathersVuexInputWrapper on a color input. Notice how the debounced callback function is provided to the `handler`. This is because color inputs trigger a `change` event every time their value changes. To prevent sending thousands of patch requests as the user changes colors, we use the debounced function to only send a request after 100ms of inactivity.
452
+
453
+
Notice also that this example uses the Vue Composition API because creating a debounced function is much cleaner this way.
0 commit comments