Universal library which helps to build OOP-driven models for GraphQL and RESTful API for Vue components. Influenced by Laravel Eloquent Models & Collections.
Note. If you looking for v1 of this library, switch to a relevant branch.
Model
is a class which acts as a base entity for your models extending this class.Repository
is a class which manages Model collections (retrieval one or many)Registry
is a Registry storageCollection
is a Proxy based on collect.js package.- Full encapsulation of GraphQL queries & mutations. No need to call them manually, all you need is to call you Model's methods.
- All arrays retrieved from GraphQL will be hydrated with respectful collections of models.
- Supports lazy-loading of GraphQL documents.
- Supports events & hooks for customization.
- TypeScript 3.9.
- Collect.JS.
- Apollo (if GraphQL activated).
npm i vue-oop -S
or
yarn add vue-oop
// Import the library itself
import VueOOP from 'vue-oop';
// Install the plugin
Vue.use(VueOOP, {
graphql: true,
schemaUrl: 'http://127.0.0.1:3000/graphql',
});
// Import the library itself
import VueOOP from 'vue-oop';
// Install the plugin
Vue.use(VueOOP);
// @/models/Client.js
import { Model } from 'vue-oop';
export default class Client extends Model {
name = 'John';
email = '[email protected]';
}
// @/repositories/ClientRepository.js
import { Repository } from 'vue-oop';
import Client from '@/models/Client';
export default class ClientRepository extends Repository {
model = Client;
// For REST
// queryMany = '/api/v1/clients';
// For GraphQL
// queryMany: () => import('@/gql/clients/queries/fetchClients.gql');
}
<template>
<ul>
<li v-if="clients.loading">Loading...</li>
<li v-else-if="clients.error">Loading Failed! Reason: {{ clients.lastError.message }}</li>
<li v-else v-for="(client, index) in clients.dataset.all()" :key="index">
<p>Name: {{ client.name }}</p>
<p>Email: {{ client.email }}</p>
</li>
</ul>
</template>
<script>
import ClientRepository from '@/repositories/ClientRepository';
export default {
data: () => ({
clients: new ClientRepository(),
}),
created() {
this.clients.many();
},
}
</script>
<template>
<ul>
<li v-if="clients.loading">Loading...</li>
<li v-else-if="clients.error">Loading Failed! Reason: {{ clients.lastError.message }}</li>
<li v-else v-for="(client, index) in clients.dataset.all()" :key="index">
<p>Name: {{ client.name }}</p>
<p>Email: {{ client.email }}</p>
</li>
</ul>
</template>
<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
import ClientRepository from '@/repositories/ClientRepository';
@Component
export default class ClientsPage extends Vue {
clients = new ClientRepository(),
created() {
this.clients.many();
}
}
</script>
Sometimes we need to be able to pass params NOT in .many()
or .one()
. It happens, for example, when .many()
is called not by you (i.e. 3rd party library or just other component).
To achieve this, you can use the following syntax:
<template>
<div>
<button v-if="userId" @click="repository.many()">Fetch</button>
</div>
</template>
<script>
// ...
data: () => ({
repository: new MyRepository(),
}),
watch: {
userId(id) {
this.repository.queryParams = { id };
},
},
// ...
</script>
Now when the userId
variable changed, the queryParams
are also updated and ready to be called.
Feel free to submit your pull-requests, ideas, proposals and bug reports!
- Add dynamic query builder & fields
- Add default fields to fetch with an ability to customize
- Add decorators
@OneToMany
,@ManyToMany
,@ManyToOne
,@OneToOne
relations between models@Field
withcastTo
,castFrom
,nullable
options
- Add subscriptions & events example
- Add cursor-based pagination
- Write more tests & coverage support
- Add scaffolding support
- Publishing as monorepo with
vue-oop-table