Categories: Vue.js

Crud Operation in Nuxt.js

In this article, we learn how to perform crud operation in nuxt.js

Roadmap for creating CRUD in Nuxt.js

  1. Install nuxt.js
  2. Overview of Vuex
  3. Perform Crud in nuxt.js

1). Install Nuxt.js

  • To get started creating our application we’ll be using create-nuxt-app. Create Nuxt App is a command line tool that helps you create and scaffold out your Nuxt applications. It helps you set up the default folder structure of your app, you can optionally install your preferred server-side framework like Express or Koa, and you can also install the Nuxt Axios module for easy Axios integration with your app.
  • To get started, make sure you’re using a version of npm that’s 5.2.0 or higher. This will ensure you have npx installed, we’ll need this command.
  • Then let’s run the following in your command in the terminal:
$ npx create-nuxt-app project-name
  • To run the app that was just created in development mode, we’ll need to cd into the directory it created for us run the following command:
    $ npm run dev

2). Overview of Vuex

  • Vuex is a state management pattern + library. It is work as a centralized storage of our data for the whole application. The basic concept is derived from React’s Redux and Flux library. Vuex comes into the picture when our client side application becomes more and more complex. If our application is not more complex, then we should not use Vuex because after using it, if you will not handle it properly then It will become tedious and cumbersome

3). CRUD in Nuxt

  • Install @nuxt/axios
npm install @nuxtjs/axios
  • Registration.vue
<template>
  <div>
    <div class="container">
      <b-form @submit="onSubmit" @reset="onReset" v-if="showForm">
        <b-form-group id="input-group-1" label="Name:" label-for="input-1">
          <b-form-input
            id="input-1"
            v-model="form.name"
            type="text"
            placeholder="Enter Name"
            required
          ></b-form-input>
        </b-form-group>

        <b-form-group id="input-group-2" label="Address:" label-for="input-2">
          <b-form-input
            id="input-2"
            v-model="form.address"
            type="text"
            placeholder="Enter Address"
            required
          ></b-form-input>
        </b-form-group>

        <b-form-group
          id="input-group-3"
          label="Email address:"
          label-for="input-3"
          description="We'll never share your email with anyone else."
        >
          <b-form-input
            id="input-3"
            v-model="form.email"
            type="email"
            placeholder="Enter email"
            required
          ></b-form-input>
        </b-form-group>

        <b-form-group id="input-group-4" label="Contact:" label-for="input-4">
          <b-form-input
            id="input-4"
            v-model="form.contact"
            type="number"
            placeholder="Enter Contact"
            required
          ></b-form-input>
        </b-form-group>

        <b-button type="submit" variant="primary">{{
          isTableDataVisible ? "Submit" : "Update"
        }}</b-button>
        <b-button type="reset" variant="danger">Reset</b-button>
      </b-form>

      <div class="mt-10 container" v-if="isTableDataVisible">
        <table class="table table-responsive">
          <tbody>
            <tr>
              <th>Id</th>
              <th>Name</th>
              <th>Address</th>
              <th>Email</th>
              <th>Contact</th>
              <th>IsActive</th>
              <th></th>
              <th>Actions</th>
            </tr>
            <tr v-for="item in form.employeeData" :key="item.id">
              <td>{{ item.id }}</td>
              <td>{{ item.name }}</td>
              <td>{{ item.address }}</td>
              <td>{{ item.email }}</td>
              <td>{{ item.contact }}</td>
              <td>
                <div class="switch">
                  <label>
                    <input type="checkbox" :checked="item.isActive" />
                    <span class="lever"></span>
                  </label>
                </div>
              </td>
              <td>
                <Editemployee :id="item.id" />
              </td>
              <td>
                <div>
                  <button class="btn btn-danger" @click="onDelete(item.id)">
                    Delete
                  </button>
                </div>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    isTableDataVisible: {
      type: Boolean,
      default: true
    },
    showForm: {
      type: Boolean,
      default: true
    }
  },

  data() {
    return {
      form: {
        email: "",
        name: "",
        address: "",
        contact: "",
        employeeData: []
      },
    };
  },
  mounted() {
    this.getData();
     this.$eventBus.on('get-data',this.getData);
  },
  methods: {
    onSubmit(event) {
      event.preventDefault();
      var params = {
        Name: this.form.name,
        Address: this.form.address,
        email: this.form.email,
        contact: this.form.contact,                                                                                                                                                                                               
        isActive: true
      };
      this.$store
        .dispatch("createOrUpdateEmployee", params)
        .then(res => {
          if (res.data != null) {
            this.getData();
            this.$notify({
              text: "Record Inserted Successfully!"
            });
          }
        })
        .catch(error => {
          console.log(error);
        });
      
    },
    onDelete(id) {
      
      this.$store.dispatch("deleteEmployee", id).then(res => {
        if (res.data.isSuccess) {
          this.getData();
          this.$notify({
            text: "Record Deleted Successfully!"
          });
        }
      });
    },
    getData() {
      this.$store.dispatch("getEmployees").then(res => {
        if (res.data.isSuccess) {
          this.form.employeeData = res.data.responseData;
        }
      });
      
    },
    onReset(event) {
      event.preventDefault();
      // Reset our form values
      this.form.email = "";
      this.form.name = "";
      this.form.address = "";
      this.form.contact = "";
      // Trick to reset/clear native browser form validation state
    }
  }
};
</script>
  • Navbar.vue
<template>
<div>
  <b-navbar toggleable="lg" type="dark" variant="info">
    <b-navbar-brand href="#">Registration Form</b-navbar-brand>

    <b-navbar-toggle target="nav-collapse"></b-navbar-toggle>

    <b-collapse id="nav-collapse" is-nav>
      <b-navbar-nav>
        <b-nav-item href="#">Edit</b-nav-item>
      </b-navbar-nav>

      <b-navbar-nav class="ml-auto">
        <b-nav-form>
          <b-form-input size="sm" class="mr-sm-2" placeholder="Search"></b-form-input>
          <b-button size="sm" class="my-2 my-sm-0" type="submit">Search</b-button>
        </b-nav-form>
        <b-nav-item-dropdown text="Lang" right>
          <b-dropdown-item href="#">EN</b-dropdown-item>
          <b-dropdown-item href="#">ES</b-dropdown-item>
          <b-dropdown-item href="#">RU</b-dropdown-item>
          <b-dropdown-item href="#">FA</b-dropdown-item>
        </b-nav-item-dropdown>

        <b-nav-item-dropdown right>
          <template #button-content>
            <em>User</em>
          </template>
          <b-dropdown-item href="#">Profile</b-dropdown-item>
          <b-dropdown-item href="#">Sign Out</b-dropdown-item>
        </b-nav-item-dropdown>
      </b-navbar-nav>
    </b-collapse>
  </b-navbar>
</div>
</template>
  • EditEmployee.vue
<template>
  <div>
    <b-button id="show-btn" @click="showModal(id)">Edit</b-button>

    <b-modal :id="id" hide-footer>
      <template #modal-title>
        Edit Employee Info
      </template>
      <div class="d-block">
        <b-form @submit="onUpdate">
          <b-form-group id="input-group-1" label="Name:" label-for="input-1">
            <b-form-input
              id="input-1"
              v-model="form.name"
              type="text"
              placeholder="Enter Name"
              required
            ></b-form-input>
          </b-form-group>

          <b-form-group id="input-group-2" label="Address:" label-for="input-2">
            <b-form-input
              id="input-2"
              v-model="form.address"
              type="text"
              placeholder="Enter Address"
              required
            ></b-form-input>
          </b-form-group>

          <b-form-group
            id="input-group-3"
            label="Email address:"
            label-for="input-3"
            description="We'll never share your email with anyone else."
          >
            <b-form-input
              id="input-3"
              v-model="form.email"
              type="email"
              placeholder="Enter email"
              required
            ></b-form-input>
          </b-form-group>

          <b-form-group id="input-group-4" label="Contact:" label-for="input-4">
            <b-form-input
              id="input-4"
              v-model="form.contact"
              type="number"
              placeholder="Enter Contact"
              required
            ></b-form-input>
          </b-form-group>
          <input type="text" v-model="hiddenId" hidden />
          <b-button type="submit" variant="primary">
            Update
          </b-button>
          <b-button type="reset" variant="danger">Reset</b-button>
        </b-form>
      </div>
      <b-button class="mt-3" block @click="$bvModal.hide(id)">Close</b-button>
    </b-modal>
  </div>
</template>
<script>
import Registration from "@/components/Registration";
export default {
  components: {
    Registration
  },
  props: {
    id: String,
  },
  data() {
    return {
      form: {
        email: "",
        name: "",
        address: "",
        contact: "",
        employeeData: []
      },
      hiddenId: ""
    };
  },

  mounted() {
  },
  methods: {
    showModal(id) {
      this.$bvModal.show(id);
      this.getEmployeeDetailsById(id);
    },
    onUpdate(event) {
      this.$bvModal.hide(this.id);
      event.preventDefault();
      var params = {
        Id: this.hiddenId,
        Name: this.form.name,
        Address: this.form.address,
        email: this.form.email,
        contact: this.form.contact,
        isActive: true
      };
      this.$store
        .dispatch("createOrUpdateEmployee", params)
        .then(res => {
          if (res.data != null) {
            this.$notify({
              text: "Record Updated Successfully!"
            });
            this.$eventBus.emit('get-data');
          }
        })
        .catch(error => {
          console.log(error);
        });
    },
    
    getEmployeeDetailsById(id) {
      this.$store.dispatch("getEmployeeByID", id).then(res => {
        if (res.data.isSuccess) {
          this.hiddenId = res.data.responseData.id;
          this.form.name = res.data.responseData.name;
          this.form.email = res.data.responseData.email;
          this.form.address = res.data.responseData.address;
          this.form.contact = res.data.responseData.contact;
        }
      });
    }
  },

  name: "Editemployee"
};
</script>
<style scoped></style>
  • Layout/default.vue
<template>
  <main>
    <Navbar />
    <notifications/>
    <Nuxt />
  </main>
</template>
  • Pages/Index.vue
<template>
  <div>
    <Registration />
  </div>
</template>

<script>
export default {};
</script>
  • Plugins

1). vue-notification-client.js

2). vue-notification-server.js

3). vue-plugin-event-bus.js

1). vue-notification-client.js

import Vue from 'vue'
import Notifications from 'vue-notification'

Vue.use(Notifications)

2). vue-notification-server.js

import Vue from 'vue'
import Notifications from 'vue-notification/dist/ssr.js'

Vue.use(Notifications)

3). vue-plugin-event-bus.js

import Vue from "vue";
import VueEventBus from "vue-plugin-event-bus"; 
 
Vue.use(VueEventBus);
  • store/action/index.js
export default {
  createOrUpdateEmployee({ commit, dispatch }, params) {
    const employeeData = params;
    commit("setData", {employeeData});
    return this.$axios.post(
      `https://localhost:44377/api/Employee/CreateOrUpdateEmployees`,
      params
    );
  },
  getEmployees({ commit, dispatch }) {
    return this.$axios.get(`https://localhost:44377/api/Employee/GetEmployees`);
  },
  getEmployeeByID({ commit, dispatch }, id) {
    return this.$axios.get(
      `https://localhost:44377/api/Employee/GetEmployeeById?id=` + id
    );
  },
  deleteEmployee({ commit, dispatch }, id) {
    return this.$axios.delete(
      `https://localhost:44377/api/Employee/DeleteEmployeeById?id=` + id
    );
  }
};
  • store/mutations/index.js
export default {
  setData(state, payload) {
    Object.keys(payload).forEach(k => {
      state[k] = payload[k];
    })
  },
};
  • store/index.js
import Vue from "vue";
import Vuex from "vuex";

import state from "./state";
import actions from "./actions";
import mutations from "./mutations";


Vue.use(Vuex);

const createStore = () => {
  return new Vuex.Store({
    state,
    actions,
    mutations,
  });
};

export default createStore;
  • state.js
export default {
  employeeData:[]
};
  • nuxt.config.js
export default {
  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    title: "nuxtcrud",
    htmlAttrs: {
      lang: "en"
    },
    meta: [
      { charset: "utf-8" },
      { name: "viewport", content: "width=device-width, initial-scale=1" },
      { hid: "description", name: "description", content: "" },
      { name: "format-detection", content: "telephone=no" }
    ],
    link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }]
  },

  // Global CSS: https://go.nuxtjs.dev/config-css
  css: [
    "bootstrap-css-only/css/bootstrap.min.css",
    "mdbvue/lib/css/mdb.min.css"
  ],

  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    { src: "~/plugins/vue-notification-client", mode: "client" },
    { src: "~/plugins/vue-notification-server", mode: "server" },
    { src: "~/plugins/vue-plugin-event-bus.js", mode: "client" }
  ],

  // Auto import components: https://go.nuxtjs.dev/config-components
  components: true,

  // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
  buildModules: [],

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    // https://go.nuxtjs.dev/bootstrap
    "bootstrap-vue/nuxt",
    "@nuxtjs/axios"
  ],

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
    extend(config, ctx) {},
    transpile: ["mdbvue/lib/components"]
  }
};
  • Output:

Bhagvat Sarvaiya

-Experienced Web Developer with a demonstrated history of working in the information technology and services industry. - ASP.NET products including Core 2.0, MVC, Web Forms,C# - Vue.js,Vuetify.js, HTML, CSS, Bootstrap, JQuery and JavaScript - API Integration with Social Media, Payment Gateways, etc. -JSON, LINQ, Microsoft Office, MySQL, Node.js, SQL, SQL Server, Visual Basic .NET, Web API -Photoshop, Wordpress, Web Designing,Theme Integration

Recent Posts

Testing hk

Testing

2 years ago

Create and Used PIPE in angular

In this article, we have to show Create and Used PIPE in angular

2 years ago

Operation

Testing

2 years ago

Create and Used PIPE in angular

In this article, we have to show Create and Used PIPE in angular

2 years ago

Create and Used PIPE in angular

In this article, we have to show Create and Used PIPE in angular

2 years ago

TETS NEW

test

3 years ago