
Article updated 2019 July 24, 1150 +8GMT
Latest release v0.2.6 (on 2019 Nov 21) Uses Vuetify 2. Please refer to This Article for v0.2 (our v0.1 refactored, improved and simplified).
This article is reserved for v0.1 updates.
The component is currently being used in production and will be continually improved based on user feedback.
There are many web-based CRUD components and applications available from the open-source community. So why build another one? Well, I would like to have a component where I can quickly build customizable admin dashboards to handle real-life use cases and vue-crud-x was created based on this need.
Other than the usual pagination, sorting and simple filters and forms, below are a few unique features and design philosophies that makes vue-crud-x stand out from the others:
- New! SSR, Generated Static Pages & Social Login Examples
- Able to do nested CRUD operations, for example selecting a post from a list of posts, and then selecting a comment from a list of comments of the selected post to edit
- Auto-generate Form & Search from JSON data
- Customizable table UI, search filters, form layout, validation
- Handling of authentication tokens, user information, permissions
- Use direct call (e.g. Firestore), or API (REST, GraphQL) to one or more types of datastore (MySQL, MongoDB, Redis, ElasticSearch, etc.)
- Pagination, search, sort, inline edit, (cache, optimistic response, refetch query on Apollo GraphQL client)
- Export to CSV, File/Image Upload, i18n
- Multiple CRUD working on a single page
- Social Login, Nuxt SSR and generated
- lit-element web-component example (https://medium.zenika.com/using-lit-element-with-vue-js-fa873df4f2a4)

Design Philosophy
- Able to build an admin dashboard quickly using the component
- Easy to maintain with as little boilerplate code as possible
- Flexibility to handle as many use cases as possible
Drawbacks
- The price to pay for the flexibility is the need for additional coding work for the customized layouts and crud operations by the developer.
This may look like a step backward, but if a custom layout or data operation is required, you will need to write the code anyway.
Getting Started
We will do a quick walk through how-to get a demo running on your local machine using the example-rest project. You may need to get up to speed on the following topics:
- Change to the example-rest directory
- Run the following commands
npm i
npm run build-rest
npm run init-db
npm run start
View the web application on http://127.0.0.1:8080, you will see the following:

Login using “test” as the username and password, click on menu icon on top left and select Books, you will see the page as shown below.

Clicking on the magnifying glass icon on the top right will open the search filter as shown below.


Inline Edit Mode
When in inline edit mode, CRUD functions can be done within the table view. However, you are not able do nested CRUD when using inline edit

Some Important Notes To Be Aware Of
Currently “id” field is required as a unique identifier and needs to be defined in your datastore. Allowing this field to be user-defined will be done in future if possible.
Customization Code Walk-through
The code snippet below is from example-rest/src/pages/Book.vue
It shows how to use vue-crud-x and customise the search filters and forms using scoped-slots, and props.
It is also a parent table in a nested CRUD use-case, where 1 book (parent) has many pages (child).
The v-autocomplete part shows how to implement a production grade autocomplete feature with rxJs, which includes debounce, and taking only latest query.
Selecting and unselecting autocomplete items show how to relate and unrelate items in a many-to-many relation (M-N).
scoped-slots
- slot=”filter” is where you customise the search filter
- slot=”form” is where you customise the form. In our nested crud use-case, there is a gotoPages() method which shows how to navigate to the pages (child table) of a selected book
- slot =”table” is where you can replace the table with your own UI component
props
- storeName holds the name of Vuex store module the vue-crud-x component will use
- parentId if not null means there is a parent table to the vue-crud-x component
- ref allows your component to access the vue-crud-x component
- @form-open listens to a “form-open” event from the crud component and allows you to write code that acts on it
- bookDefs is the data object with the properties to setup and configure the vue-crud-x component. The main properties are crudTable, crudFilter and crudForm, crudOps, and they are explained below
crudOps
This contains the crud operations for the vue-crud-x component, available actions are export(), find(), findOne(), update(), create(), delete().
crudFilter
This contains the fields that will be filtered and the UI component used for each filter
crudForm
This contains the fields for the input form, the properties should match or be a subset of what is read from the findOne() operation
crudTable
Configuration for the vue-crud-x component table, headers, inline edits, confirmations, styling, etc.
Child Table, Inline Edit & Export Walk-through
The code snippet below is from example-rest/src/pages/Page.vue
It shows how the implement child table of a nested CRUD and CSV/JSON export, as well as configuration for inline edit.
In our case this component list the pages (child) of a selected book (parent)
The parentId passed in, indicates that this is a child table.
The property pageDefs.crudTable.showGoBack is set to true, to indicate that you want a button to go back to the parent table. You can also implement your own code which will call this.$router.back().
// INLINE EDIT - START and // INLINE EDIT - END shows the parts of code to configure inline editing.
The function pageDefs.crudOps.export(), shows how to export data to CSV/JSON
Projects In The Repository
There are example 4 projects in this repository which illustrate complete use-cases including the backend.
The projects are listed below and indicate any additional examples of supporting technologies such as Server-side rendering, reactive programming, etc.
example-rest
- rxJS, autocomplete
- Web-sockets
- 2FA using Google Authenticator
- GraphQL
example-firebase
- Google Firebase, Firestore, Authentication, Recaptcha
- Webcam image capture and upload to cloud storage
- Use and interaction of multiple vue-crud-x components in a single page
example-nuxt
- Server-side rendering (SSR)
- Generated Static Pages
- Social Login
backend
- objectionJS (ORM), Sqlite, mongoDB, GraphQL
- Key-value store (& Redis)
- OpenAPI
- Social Login
Final Words
I hope that you will find this article useful, vue-crud-x is continually improved and contributors are welcome to help make it better and address more production use-cases.
If there are any features that I may have missed out, you can raise an issue on Github.
Should you have any questions you can reach out via email or on telegram @aaronjxz, if they cannot be resolved here.
Thank you for reading this rather long article and happy coding!
Supplementary Article - Setup For “example” Project
Below are additional setup information to help get the example project, which uses Firebase as a backend, to run.
Signing Up For Firebase
- Create a new google account or use an existing google account
- Goto Google Firebase and signup for firebase, you may need to enter your credit card information to access their services
- Create a user (https://firebase.google.com/docs/auth/web/password-auth), you will need this user to log in to the example program
- Enable your firestore and enable read-write in the rules


Get Your Credentials
See picture below on where to get your firebase credentials

Your credentials should look like the JSON below…
<script src="https://www.gstatic.com/firebasejs/4.13.0/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "..."
};
firebase.initializeApp(config);
</script>
Use the information in var config, save it in a file called cfg.json
Create Firestore Collections
- party Collection and sample Document

2. note Collection and sample Document

Relationship
One party (e.g. a party to a lawsuit) can have zero or more notes (e.g. case notes)
One note belongs to only one party
The parent Key for the note Collection sample document shown above is “party” and relates to the “name” field in the party Collection document
Create Indexes
See picture below on the indexes to create for the note collection.

Google Recaptcha
If you want to use Recaptcha in the login process, you can sign up for your own Recaptcha site-key from Google Recaptcha.
NOTE: Recaptcha is bypassed when the client detects the host serving the page is 127.0.0.1 or localhost, so you do not need Recaptcha site-key in development environment.
File Upload (this documentation is work-in-progess)
The ImageUpload.vue component can now be added to a crud form to upload images to Firebase storage and save its path to an existing record.

Check your firebase storage for the image after clicking upload button.