Vue Firebase CRUD Example is the today’s leading topic. If you are new to both Vue and Firebase, then you can check out my another tutorial Vue Firebase Example. It will help you to up and running with Vue and Firebase and how we can connect each other. Now, let us straight to the point and get started.
Vue Firebase CRUD Example
Our complete app looks like this.
First, install a Vue project.
Step 1: Install Vue using vue cli.
Go to the terminal and hit the following command.
npm install -g @vue/cli or yarn global add @vue/cli
Step 2: Install vuefire for firebase vue binding.
Okay, now create a project using the following command.
vue create vuefirebaseexample
Go into the project.
cd vuefirebaseexample
Install the vuefire library using the following command.
yarn add vuefire firebase or npm install vuefire firebase --save
Import vuefire inside a main.js file.
// main.js import Vue from 'vue' import VueFire from 'vuefire' import App from './App.vue' Vue.use(VueFire) Vue.config.productionTip = false new Vue({ render: h => h(App) }).$mount('#app')
Step 3: Create three components.
First, include the Bootstrap 4 in our project.
yarn add bootstrap # or npm install bootstrap --save
Include inside App.vue file.
<style lang="css"> @import '../node_modules/bootstrap/dist/css/bootstrap.min.css'; </style>
Inside src >> components folder, create the following three files.
- AddItem.vue
- EditItem.vue
- ListItem.vue
- Home.vue
Now, add the following code to each component. After that, we create the route for our application.
// Home.vue <template> <h1>Home</h1> </template> <script> export default { components: { name: 'Home' } } </script>
// AddItem.vue <template> <h1>Add Item</h1> </template> <script> export default { components: { name: 'AddItem' } } </script>
// EditItem.js <template> <h1>Edit Item</h1> </template> <script> export default { components: { name: 'EditItem' } } </script>
// ListItem.vue <template> <h1>List Item</h1> </template> <script> export default { components: { name: 'ListItem' } } </script>
Step 4: Install and configure the router.
Install the vue-router dependency.
yarn add vue-router # or npm install vue-router --save
Now, we need to configure the routes. So let us add the following code to the main.js file.
// main.js import Vue from 'vue' import VueFire from 'vuefire' import VueRouter from 'vue-router' import App from './App.vue' import AddItem from './components/AddItem.vue' import EditItem from './components/EditItem.vue' import ListItem from './components/ListItem.vue' import Home from './components/Home.vue' Vue.use(VueFire) Vue.use(VueRouter) Vue.config.productionTip = false const routes = [ { name: 'Home', path: '/', component: Home }, { name: 'Add', path: '/add', component: AddItem }, { name: 'Edit', path: '/edit/:id', component: EditItem }, { name: 'List', path: '/index', component: ListItem }, ]; const router = new VueRouter({ mode: 'history', routes: routes }); new Vue({ render: h => h(App), router }).$mount('#app')
Also, we need to define our router output. It means that, when we change the route, we need to display that component. So add the <router-view> inside App.vue file.
// App.vue <template> <div id="app"> <router-view></router-view> </div> </template> <script> <style lang="css"> @import '../node_modules/bootstrap/dist/css/bootstrap.min.css'; </style>
Save the file and start the development server using the following command.
npm run serve
Go to this URL: http://localhost:8080/index
You can see our route is working. Now, we need to style our application.
Step: 5: Add Bootstrap Navigation.
We need to modify the App.vue file to add the Bootstrap Navigation.
// App.vue <template> <div id="app" class="container"> <nav class="navbar navbar-expand-sm bg-light"> <ul class="navbar-nav"> <li class="nav-item"> <router-link :to="{ name: 'Home' }" class="nav-link">Home</router-link> </li> <li class="nav-item"> <router-link :to="{ name: 'Add' }" class="nav-link">Add Item</router-link> </li> <li class="nav-item"> <router-link :to="{ name: 'List' }" class="nav-link">All Item</router-link> </li> </ul> </nav> <div class="gap"> <router-view></router-view> </div> </div> </template> <style lang="css"> @import '../node_modules/bootstrap/dist/css/bootstrap.min.css'; </style> <style> .gap { margin-top: 50px; } </style> <script> export default { name: 'app' } </script>
Step 6: Add Routing Progress bar Indicator.
Type the following command to install nprogress. It is a library that provides us the UI component that displays the routing indicator.
yarn add nprogress # or npm install nprogress --save
Add its CSS inside a main.js file.
// main.js import '../node_modules/nprogress/nprogress.css'
Now, we need to add a hook to the router object. So when we change the route, it starts the progress bar at the top and when the routing process finishes, we need to stop that progress bar from showing in the header.
// main.js import Vue from 'vue' import VueFire from 'vuefire' import VueRouter from 'vue-router' import NProgress from 'nprogress'; import App from './App.vue' import AddItem from './components/AddItem.vue' import EditItem from './components/EditItem.vue' import ListItem from './components/ListItem.vue' import Home from './components/Home.vue' import '../node_modules/nprogress/nprogress.css' Vue.use(VueFire) Vue.use(VueRouter) Vue.config.productionTip = false const routes = [ { name: 'Home', path: '/', component: Home }, { name: 'Add', path: '/add', component: AddItem }, { name: 'Edit', path: '/edit/:id', component: EditItem }, { name: 'List', path: '/index', component: ListItem }, ]; const router = new VueRouter({ mode: 'history', routes: routes }); router.beforeResolve((to, from, next) => { if (to.name) { NProgress.start() } next() }) router.afterEach(() => { NProgress.done() }) new Vue({ render: h => h(App), router }).$mount('#app')
Now, you can see that Progress bar is running after changing the route.
Step 7: Create a form to add an Item.
Now, we need to create a basic form inside AddItem.vue.
// AddItem.vue <template> <div class="container"> <div class="card"> <div class="card-header"> <h3>Add Item</h3> </div> <div class="card-body"> <form v-on:submit.prevent="addItem"> <div class="form-group"> <label>Item Name:</label> <input type="text" class="form-control"/> </div> <div class="form-group"> <label>Item Price:</label> <input type="text" class="form-control"/> </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="Add Item"/> </div> </form> </div> </div> </div> </template> <script> export default { components: { name: 'AddItem' } } </script>
So, our form looks like this.
Step 8: Connect Vue to the Firebase.
Go to Firebase and login to your console account.
Create one project.
Please enable to reading and writing in test mode for our application. Otherwise, you will not be able to store any data on the firebase.
Now, after that, you need to create a database for the web application, and then you will get your configuration object like below.
let config = { apiKey: "", authDomain: "", databaseURL: "", projectId: "", storageBucket: "", messagingSenderId: "" };
Okay, now inside src folder, create one folder called config. Inside that folder, create one file called db.js.
// db.js import Firebase from 'firebase' let config = { apiKey: "", authDomain: "", databaseURL: "", projectId: "", storageBucket: "", messagingSenderId: "" }; let app = Firebase.initializeApp(config) export const db = app.database()
I have created this separate file because when we need to perform any database operations, we can connect the component separately to the database directly.
Step 9: Add Items to the Firebase.
Okay, so we need to create one object that has name and price as a property and then add that object to the Firebase method to add the items to the Firebase database. We need to require the db.js file to connect our application to the Firebase.
// AddItem.vue <template> <div class="container"> <div class="card"> <div class="card-header"> <h3>Add Item</h3> </div> <div class="card-body"> <form v-on:submit.prevent="addItem"> <div class="form-group"> <label>Item Name:</label> <input type="text" class="form-control" v-model="newItem.name"/> </div> <div class="form-group"> <label>Item Price:</label> <input type="text" class="form-control" v-model="newItem.price"/> </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="Add Item"/> </div> </form> </div> </div> </div> </template> <script> import { db } from '../config/db'; export default { components: { name: 'AddItem' }, firebase: { items: db.ref('items') }, data () { return { newItem: { name: '', price: '' } } }, methods: { addItem() { this.$firebaseRefs.items.push({ name: this.newItem.name, price: this.newItem.price }) this.newItem.name = ''; this.newItem.price = ''; this.$router.push('/index') } } } </script>
If your database configuration is set correctly, then you can add the items to the Firebase, and you can see the alert that says that we have successfully implemented the add item functionality.
Step 10: Display the data from Firebase.
Now, write the following code inside ListItem.vue file.
// ListItem.vue <template> <div> <h1>List Item</h1> <table class="table table-striped"> <thead> <tr> <th>Item Name</th> <th>Item Price</th> <th colspan="2">Action</th> </tr> </thead> <tbody> <tr v-for="item of items" :key="item['.key']"> <td>{{ item.name }}</td> <td>{{ item.price }}</td> <td> <router-link :to="{ name: 'Edit', params: {id: item['.key']} }" class="btn btn-warning"> Edit </router-link> </td> </tr> </tbody> </table> </div> </template> <script> import { db } from '../config/db'; export default { components: { name: 'ListItem' }, data() { return { items: [] } }, firebase: { items: db.ref('items') } } </script>
Step 11: Update the data to the Firebase.
Now, we need to add an edit form to the EditItem.vue file.
// EditItem.vue <template> <div class="container"> <div class="card"> <div class="card-header"> <h3>Edit Item</h3> </div> <div class="card-body"> <form v-on:submit.prevent="updateItem"> <div class="form-group"> <label>Item Name:</label> <input type="text" class="form-control" v-model="newItem.name"/> </div> <div class="form-group"> <label>Item Price:</label> <input type="text" class="form-control" v-model="newItem.price" /> </div> <div class="form-group"> <input type="submit" class="btn btn-primary" value="Update Item"/> </div> </form> </div> </div> </div> </template> <script> import { db } from '../config/db'; export default { components: { name: 'EditItem' }, firebase: { items: db.ref('items'), itemsObj: { source: db.ref('items'), asObject: true } }, data () { return { newItem: {} } }, created() { let item = this.itemsObj[this.$route.params.id] this.newItem = { name: item.name, price: item.price } }, methods: { updateItem() { this.$firebaseRefs.items.child(this.$route.params.id).set(this.newItem); this.$router.push('/index') } } } </script>
In this code, first, when the component is created, we fetch the data from the key in the firebase.
Then we bind that data to the newItem object. Here, two way data binding will help is to show the data in the form.
At last, we update the item.
Step 12: Delete the data.
Finally, add the delete code inside ListItem.vue file.
// ListItem.vue <tbody> <tr v-for="item of items" :key="item['.key']"> <td>{{ item.name }}</td> <td>{{ item.price }}</td> <td> <router-link :to="{ name: 'Edit', params: {id: item['.key']} }" class="btn btn-warning"> Edit </router-link> </td> <td> <button @click="deleteItem(item['.key'])" class="btn btn-danger">Delete</button> </td> </tr> </tbody>
Now, create the deleteItem function.
// ListItem.vue <script> import { db } from '../config/db'; export default { components: { name: 'ListItem' }, data() { return { items: [] } }, firebase: { items: db.ref('items') }, methods: { deleteItem(key) { this.$firebaseRefs.items.child(key).remove(); } } } </script>
So, our whole ListItem.vue file looks like this.
// ListItem.vue <template> <div> <h1>List Item</h1> <table class="table table-striped"> <thead> <tr> <th>Item Name</th> <th>Item Price</th> <th colspan="2">Action</th> </tr> </thead> <tbody> <tr v-for="item of items" :key="item['.key']"> <td>{{ item.name }}</td> <td>{{ item.price }}</td> <td> <router-link :to="{ name: 'Edit', params: {id: item['.key']} }" class="btn btn-warning"> Edit </router-link> </td> <td> <button @click="deleteItem(item['.key'])" class="btn btn-danger">Delete</button> </td> </tr> </tbody> </table> </div> </template> <script> import { db } from '../config/db'; export default { components: { name: 'ListItem' }, data() { return { items: [] } }, firebase: { items: db.ref('items') }, methods: { deleteItem(key) { this.$firebaseRefs.items.child(key).remove(); } } } </script>
Finally, our Vue Firebase CRUD Example Tutorial is over. We have done successfully all the CRUD operations inside Vue Application.
Thanks for this, I’ll work through it.
But one trivial point. Step 2 will fail, the directory needs to be created.
I assume everything is being created manually? And the Vue cli is not being used to create the app?
Thanks Dave
Thanks for suggestion, I have forgotten to write the command to generate the Vue project using vue-cli. I have fixed it.
Would love to see a Vue.js crud example with Django integration! Thank for sharing.
Thanks for the great article!
Any suggestions or resources you could point me to for deleting the current item you are viewing? Say you drilled into one of those items from a list view and wanted a button to delete it from within?
if i want make a modal bootrap on delete data?
God bless you so much for this guide.
[…] Vue Firebase CRUD Example […]