Skip to content

Instantly share code, notes, and snippets.

@ais-one
Last active July 24, 2019 02:29
Show Gist options
  • Save ais-one/cfb2c9dfa1713f2d8d634078606ade3f to your computer and use it in GitHub Desktop.
Save ais-one/cfb2c9dfa1713f2d8d634078606ade3f to your computer and use it in GitHub Desktop.
Vue-Crud-X Sample
<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