Instantly share code, notes, and snippets.
Last active
July 24, 2019 02:29
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save ais-one/cfb2c9dfa1713f2d8d634078606ade3f to your computer and use it in GitHub Desktop.
Vue-Crud-X Sample
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div> | |
<v-layout row wrap> | |
<v-flex xs12> | |
<!-- | |
This is the CRUD Component | |
ref: to allow access to the component methods and data | |
parentId: not Null indicates the parent ID | |
v-bind: see script for explnation of the various properties used in this example | |
--> | |
<vue-crud-x ref="author" :parentId="parentId" v-bind="authorDefs" /> | |
</v-flex> | |
</v-layout> | |
</div> | |
</template> | |
<script> | |
import { http } from '@/axios' | |
export default { | |
name: 'author', | |
data () { | |
return { | |
parentId: null, | |
// This property is passed into the CRUD component | |
authorDefs: { | |
infinite: true, // indicate that table is infinite scroll, not paged | |
// this is to configure the table (specifically for Vuetify v-data-table, it will be different for Ant Design and ElementUI, etc.) | |
vtable: { | |
// this follows the headers property in v-data-table | |
// we also added render for formatting cells | |
// edit: null indicates the table column is not editable (when inline edit is enabled) | |
// vue-crud-x/example-spa/pages/FirebaseRT.vue example shows inline edit usage | |
headers: [ | |
{ text: 'Author Name', value: 'name', class: 'pa-1', render: (value) => value, edit: null } | |
] | |
}, | |
// this tells what is the default start page (or cursor for infinite scroll) | |
// and also so number of rows per page... | |
// for more details on the properties, refer to: https://github.com/ais-one/vue-crud-x/blob/v2/docs/VueCrudX.md | |
pageDefaults: { | |
start: 1 | |
}, | |
// this is not used as sort has no meaning in pagination, also in Vuetify, sort settings is actually done in pageDefaults | |
sortDefaults: { | |
}, | |
// this indicates the filters when doing find in CRUD | |
// this will autogenerate filter inputs, but define you can use your own custom filter and layouts also | |
// see vue-crud-x/example-spa/pages/Book.vue for example | |
filters: { | |
// this is a name given to a search, for example 'startDate' and 'endDate' is the names of 2 filters | |
// you use these two to find rows with a date between those two filters | |
// e.g. Birthday > startDate && Birthday < endDate | |
'name': { | |
// this is a vuetify input component name (can also be your custom component) | |
type: 'v-text-field', | |
// this is the default value of the filter | |
value: '', | |
// this is the attributes of the component wrapping the input | |
'field-wrapper': { xs12: true, sm6: true }, | |
// this is the attibutes used by that input type | |
'field-input': { | |
label: 'Author', clearable: true | |
} | |
} | |
}, | |
// this is to describe the CRUD input form for add/update | |
// this will autogenerate form inputs, but define you can use your own custom form and layouts also | |
// see vue-crud-x/example-spa/pages/Book.vue for example | |
form: { | |
// this is the form item name, it should match DB record field name | |
'id': { | |
// this is a vuetify input component name (can also be your custom component) | |
type: 'v-text-field', | |
// this holds the current value | |
value: '', | |
// this is the default value | |
default: '', | |
// set if field is to be hidden or not | |
hidden: 'add', // add, edit, all, null | |
// set if field is to be readonly or not | |
readonly: 'all', // add, edit, all, null | |
// validation function not in place yet | |
validation: null, | |
// SAME AS FILTER | |
'field-wrapper': { xs12: true, sm6: true }, | |
// SAME AS FILTER | |
'field-input': { | |
label: 'ID' | |
} | |
}, | |
'name': { | |
type: 'v-text-field', | |
value: '', | |
default: '', | |
'field-wrapper': { xs12: true, sm6: true }, | |
'field-input': { | |
label: 'Name', | |
rules: [v => !!v || 'Item is required'] | |
} | |
}, | |
'avatar': { | |
type: 'app-file-upload', | |
value: { savedUrl: 'aa', imageName: '', imageUrl: '', imageFile: '' }, | |
default: '', | |
'field-wrapper': { xs12: true, sm6: true }, | |
'field-input': { | |
label: 'Avatar' | |
} | |
} | |
}, | |
// THIS IS WHERE THE CRUD OPERATIONS IS DEFINED | |
// For details of the inputs and outputs of each method, | |
// refer to: https://github.com/ais-one/vue-crud-x/blob/v2/docs/VueCrudX.md | |
crud: { | |
find: async (payload) => { | |
let records = [] | |
let totalRecords = 0 | |
const { pagination, filters = {}, sorters = {} } = payload // sorters = {} not used as it is in pagination for vuetify | |
console.log(pagination, filters, sorters) | |
const { page, itemsPerPage } = pagination | |
let params = { page: page > 0 ? page - 1 : 0, limit: itemsPerPage, ...filters, sort: sorters } // set query params | |
try { | |
const { data: { results, total } } = await http.get('/api/authors', { params }) | |
records = results | |
totalRecords = total | |
// simulate infinite scroll | |
const totalPages = Math.ceil(total / params.limit) | |
let cursor = 0 | |
if (page < totalPages) cursor = page + 1 | |
else cursor = 0 | |
return { status: 200, data: { records, totalRecords, cursor } } | |
} catch (e) { | |
return { status: e.response.status, error: e.toString() } | |
} | |
}, | |
findOne: async (id) => { | |
try { | |
const { data } = await http.get(`/api/authors/${id}`) | |
data.avatar = { savedUrl: data.avatar, imageName: '', imageUrl: '', imageFile: '' } | |
console.log('data', data) | |
return { status: 200, data } | |
} catch (e) { | |
return { status: e.response.status, error: e.toString() } | |
} | |
}, | |
create: async ({ record }) => { | |
try { | |
let { id, ...noIdData } = record | |
const { data } = await http.post('/api/authors', noIdData) | |
return { status: 201, data } | |
} catch (e) { | |
return { status: e.response.status, error: e.toString() } | |
} | |
}, | |
update: async ({ record }) => { | |
try { | |
const { id, name, avatar } = record | |
const json = JSON.stringify({ name }) | |
const formData = new FormData() | |
formData.append('filex', avatar.imageFile) // const { name, size, type } = avatar.imageFile | |
formData.append('docx', json) | |
const { data } = await http.patch(`/api/authors/${id}`, formData, | |
{ | |
headers: { | |
'Content-Type': 'multipart/form-data' | |
} | |
} | |
) | |
return { status: 200, data } | |
} catch (e) { | |
return { status: e.response.status, error: e.toString() } | |
} | |
}, | |
'delete': async (id) => { | |
try { | |
const { data } = await http.delete(`/api/authors/${id}`) | |
return { status: 200, data } | |
} catch (e) { | |
return { status: e.response.status, error: e.toString() } | |
} | |
} // done | |
} | |
} | |
} | |
} | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment