Package Exports
- vuex-loopback
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (vuex-loopback) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Installing
1. Install axios and vuex-loopback.
yarn add axios vuex-loopbackor via npm
npm install axios vuex-loopback2. Import axios and module factory.
import axios from 'axios';
import {createModule} from 'vuex-loopback';3. Create axios instance with baseURL option.
const client = axios.create({
baseURL: 'https://my-domain.com/api/',
});Create Vuex module
Before use built-in components ItemsLoader and ItemEditor you need to create Vuex modules for each Loopback collections that you want to manage. For example we will create named module articles for the Articles collection.
1. Define collection model with default fields.
const model = {
id: '',
name: '',
}2. Use module factory to create Vuex module.
new Vuex.Store({
modules: {
// ...
articles: {
namespaced: true,
...createModule({
client, // (required) Axios instance.
model, // (required) Collection model.
collection: 'Articles', // (required) Plural collection name.
state: {}, // Extend default state.
getters: {}, // Extend default getters.
actions: {}, // Extend default actions.
mutations: {}, // Extend default mutations.
}),
},
// ...
}
});Load items
Built-in component ItemsLoader will help you to load collection items right in Vue template. A scope of default slot has some usefull methods and properties to create items list with lazy-load or pagination behaviours.
Props
module: string- Name of Vuex module.noAutoload: boolean- Do not autoload items after mount.
Scope of default slot
items: object[]- Loaded items.loading: boolean- Loading state.page: number- Current page.pages: number- Total number of pages.hasMore: boolean- Can we load more?load()- Load items.loadPage(page: number)- Load specific page.loadMore()- Load more items.
* Component will load items automatically if prop noAutoload has not specified.
* All properties and methods of slot scope are accessible by component reference (ref attribute).
Basic example
1. Import ItemsLoader from vuex-loopback.
import {ItemsLoader} from 'vuex-loopback';2. Define local component.
export default {
// ...
components: {
ItemsLoader,
},
// ...
}3. Use it to load collection items.
<!-- Loader -->
<items-loader
module="articles">
<template
slot-scope="{items, hasMore, loadMore}">
<!-- Item -->
<div
:key="item.id"
v-for="item in items">
{{ item.name }}
</div>
<!-- More Button -->
<button
v-if="hasMore"
@click="loadMore">
More
</button>
</template>
</items-loader>Manage an item
You are able to create, update or remove collection item by built-in component ItemEditor. Same as above ItemEditor has a scope of default slot which provides specific methods and properties.
Props
module: string- Name of Vuex module.extend: object- Extend an item fields.
Scope of default slot
item: object- Selected item.loading: boolean- Loading state.edit(item: object)- Select or create item if no argument specified.set(item: object)- Update selected or created item temporary.save()- Commit temporary changes applied by methodset.remove()- Remove selected item from collection.
* All properties and methods of slot scope are accessible by component reference (ref attribute).
Basic example
1. Import ItemEditor from vuex-loopback.
import {ItemEditor} from 'vuex-loopback'; // new line
import {ItemsLoader} from 'vuex-loopback';2. Define local component.
export default {
// ...
components: {
ItemEditor, // new line
ItemsLoader,
},
// ...
}3. Use it to create editor form.
<!-- Editor -->
<item-editor
ref="editor"
module="articles">
<template
slot-scope="{item, set, save, remove}">
<form
@submit.prevent="save">
<!-- Name Field -->
<input
:value="item.name"
@input="set({...item, name: $event})"/>
<!-- Save Button -->
<button
type="submit">
Save
</button>
<!-- Remove Button -->
<button
v-if="item.id"
@click="remove">
Remove
</button>
</form>
</template>
</item-editor>4. Update items loader template.
<!-- Loader -->
<items-loader
module="articles">
<template
slot-scope="{items, hasMore, loadMore}">
<!-- Item -->
<div
:key="item.id"
v-for="item in items">
{{ item.name }}
<!-- Edit Button -->
<button
@click="() => $refs.editor.show(item)">
Edit
</button>
</div>
<!-- More Button -->
<button
v-if="hasMore"
@click="loadMore">
More
</button>
<!-- Create Button -->
<button
@click="() => $refs.editor.show()">
Create
</button>
</template>
</items-loader>Advanced usage
You may want to use Vuex module directly.
Let's see what it has.
State
item: object = null- Loaded item.tempItem: object = null- Clone ofitem.items: object[] = []- Loaded items.skip: number = 0- Items offset.limit: number = 20- Items limit.total: number = 0- Total items.orderBy: string = ''- Sort by field.orderDesc: boolean = ''- Sort descending.searchBy: string[] = ['name']- Search by fields.searchQuery: string = ''- Searching query.where: object = {}- Fetching condition.loading: boolean = false- Loading state.include: string[] = []- Fetching relations.fields: string[] = []- Fetching fields.
Getters
page: number- Number of current page.totalPages: number- Number of total pages.hasMore: boolean- Can we load more? (lazy loading)
Mutations
RESETSET_ITEM(value: object)RESET_ITEMSET_TEMP_ITEM(value: object)RESET_TEMP_ITEMSET_ITEMS(value: object[])RESET_ITEMSSET_SKIP(value: number)RESET_SKIPSET_LIMIT(value: number)RESET_LIMITSET_TOTAL(value: number)RESET_TOTALSET_ORDER_BY(value: string)RESET_ORDER_BYSET_ORDER_DESC(value: boolean)RESET_ORDER_DESCSET_SEARCH_BY(value: string[])RESET_SEARCH_BYSET_SEARCH_QUERY(value: string)RESET_SEARCH_QUERYSET_WHERE(value: object)RESET_WHERESET_LOADING(value: boolean)RESET_LOADINGSET_INCLUDE(value: string[])RESET_INCLUDESET_FIELDS(value: string[])RESET_FIELDSUPDATE_ITEM(item: object)REMOVE_ITEM(id: number|string)
Actions:
FETCH_ITEM(payload)id: number|stringfilter: object = {}noTempItem: boolean = false
FETCH_ITEMS(payload)filter: object = {}noGlobals: boolean = falseappend: boolean = false
CREATE_ITEM(payload)data: objectfilter: object = {}
PATCH_ITEM(payload)id: number|stringdata: objectfilter: object = {}
REMOVE_ITEM(id: number|string)CREATE_TEMP_ITEM(item: object = null)PUT_TEMP_ITEM(payload)filter: object = {}noPatch: boolean = falsereset: boolean = false
SEARCH_ITEMS(payload)query: string = ''searchBy: string[] = null
FETCH_PAGE(payload)page: number = 1
FETCH_MORE()
Tests
1. Clone loopback-example-relations and start web-server.
git clone https://github.com/strongloop/loopback-example-relations.git
cd loopback-example-relations
yarn
yarn start2. Clone vuex-loopback in a new terminal session and run the tests.
git clone https://github.com/mikeevstropov/vuex-loopback.git
cd vuex-loopback
yarn
yarn testExamples
Vue CLI project vuex-loopback-example
Todo
- State factory.
- Mutations factory.
- Actions factory.
- Getters factory.
- Loader component.
- Editor component.
- Documentation.
- Examples.