Membuat Kalender Menggunakan Vue - CRUDPRO

Membuat Kalender Menggunakan Vue

Perekaman tanggal adalah fitur penting di banyak aplikasi. Memiliki kalender seringkali merupakan fitur yang berguna untuk dimiliki. Untungnya, banyak pengembang telah membuat component kalender yang dapat ditambahkan dengan mudah oleh pengembang lain ke aplikasi mereka.

Vue.js memiliki banyak widget kalender yang dapat Anda tambahkan ke aplikasi Anda. Salah satunya adalah kalender lengkap Vue.js. Ini memiliki banyak fitur. Ada kalender untuk bulan, minggu dan hari. Anda juga dapat dengan mudah menavigasi hari ini atau hari lainnya menggunakan tombol Kembali dan Berikutnya. Anda juga dapat memilih rentang tanggal dengan menyeret rentang tanggal pada kalender. Sekarang Anda dapat menggunakan tanggal untuk melakukan apa pun yang Anda inginkan.

Dalam artikel ini, kami akan membuat aplikasi kalender sederhana yang memungkinkan pengguna menyeret rentang tanggal untuk menambahkan entri kalender. Pengguna juga dapat mengklik entri kalender yang ada untuk mengedit entri. Anda juga dapat menghapus entri yang ada. form untuk menambahkan dan mengedit entri kalender memiliki pemilih tanggal dan waktu untuk memilih tanggal dan waktu.

Simpan data backend ke file JSON.

Bangun aplikasi Anda menggunakan Vue.js. Pertama, jalankan perintah berikut:

npx @vue/cli create calendar-app

Kemudian pilih Manually select features, pilih Babel, CSS preprocessor, Vue router, Vuex.

Setelah membuat aplikasi, Anda harus menginstal beberapa paket yang diperlukan. Axios diperlukan untuk mengirim permintaan HTTP ke backend. BootstrapVue untuk styling, jQuery dan Moment adalah dependensi dari paket Vue-Full-Calendar yang digunakan untuk menampilkan kalender. Validasi untuk validasi form Vee, gunakan Vue-Ctk-Date-Time-Picker untuk memungkinkan pengguna memilih tanggal dan waktu event kalender dan gunakan Vue-Full-Calendar untuk widget kalender.

Kita jalanakan pada command:

npx @vue/cli create calendar-app

Kemudian pilih Manually select features, pilih Babel, CSS preprocessor, Vue router, Vuex.

Setelah membuat aplikasi, Anda harus menginstal beberapa paket yang diperlukan. Axios diperlukan untuk mengirim permintaan HTTP ke backend. BootstrapVue untuk styling, jQuery dan Moment adalah dependensi dari paket Vue-Full-Calendar yang digunakan untuk menampilkan kalender. Validasi untuk validasi form Vee, gunakan Vue-Ctk-Date-Time-Picker untuk memungkinkan pengguna memilih tanggal dan waktu event kalender dan gunakan Vue-Full-Calendar untuk widget kalender.

jalankan

npm i axios bootstrap-vue jquery moment vee-validate vue-ctk-date-time-picker vue-full-calendar

Instal semua paket.

Setelah semua paket diinstal, Anda dapat mulai membangun aplikasi Anda. Mulailah dengan form untuk mengisi entri kalender.

Buat file bernama CalendarForm.vue di folder component Anda dan tambahkan yang berikut ini:

<template>
  <div>
    <ValidationObserver ref="observer" v-slot="{ invalid }">
      <b-form @submit.prevent="onSubmit" novalidate>
        <b-form-group label="Title" label-for="title">
          <ValidationProvider name="title" rules="required" v-slot="{ errors }">
            <b-form-input
              :state="errors.length == 0"
              v-model="form.title"
              type="text"
              required
              placeholder="Title"
              name="title"
            ></b-form-input>
            <b-form-invalid-feedback :state="errors.length == 0">Title is required</b-form-invalid-feedback>
          </ValidationProvider>
        </b-form-group><b-form-group label="Start" label-for="start">
          <ValidationProvider name="start" rules="required" v-slot="{ errors }">
            <VueCtkDateTimePicker
              input-class="form-control"
              :state="errors.length == 0"
              v-model="form.start"
              name="start"
            ></VueCtkDateTimePicker>
            <b-form-invalid-feedback :state="errors.length == 0">Start is required</b-form-invalid-feedback>
          </ValidationProvider>
        </b-form-group>        <b-form-group label="End" label-for="end">
          <ValidationProvider name="end" rules="required" v-slot="{ errors }">
            <VueCtkDateTimePicker
              input-class="form-control"
              :state="errors.length == 0"
              v-model="form.end"
              name="end"
            ></VueCtkDateTimePicker>
            <b-form-invalid-feedback :state="errors.length == 0">End is required</b-form-invalid-feedback>
          </ValidationProvider>
        </b-form-group>        <b-button type="submit" variant="primary">Save</b-button>
        <b-button type="button" variant="primary" @click="deleteEvent(form.id)">Delete</b-button>
      </b-form>
    </ValidationObserver>
  </div>
</template><script>
import { requestsMixin } from "../mixins/requestsMixin";
import * as moment from "moment";export default {
  name: "CalendarForm",
  props: {
    edit: Boolean,
    calendarEvent: Object
  },
  mixins: [requestsMixin],
  data() {
    return {
      form: {}
    };
  },
  watch: {
    calendarEvent: {
      immediate: true,
      deep: true,
      handler(val, oldVal) {
        this.form = val || {};
      }
    }
  },
  methods: {
    async onSubmit() {
      const isValid = await this.$refs.observer.validate();
      if (!isValid) {
        return;
      }
      this.form.start = moment(this.form.start).format("YYYY-MM-DD HH:mm:ss");
      this.form.end = moment(this.form.end).format("YYYY-MM-DD HH:mm:ss");      if (this.edit) {
        await this.editCalendar(this.form);
      } else {
        await this.addCalendar(this.form);
      }
      const response = await this.getCalendar();
      this.$store.commit("setEvents", response.data);
      this.$emit("eventSaved");
    },    async deleteEvent(id) {
      await this.deleteCalendar(id);
      const response = await this.getCalendar();
      this.$store.commit("setEvents", response.data);
      this.$emit("eventSaved");
    }
  }
};
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
button {
  margin-right: 10px;
}
</style>

File ini menggunakan component form BootstrapVue untuk membuat form. Gunakan VueCtkDateTimePicker untuk menambahkan pemilih tanggal dan waktu ke form Anda, memungkinkan pengguna untuk memilih waktu dan tanggal.

Bungkus setiap input dalam component ValidationProvider sehingga setiap kolom dapat divalidasi. Setiap field wajib diisi, jadi atur rules prop ke required.

kita set :state binding ke error.length == 0 untuk menampilkan kesalahan hanya jika panjang arrays errors lebih besar dari 0. Ini juga berlaku untuk component b-form-invalid-feedback.

form memiliki tombol Simpan onSubmit untuk melakukan saat tombol diklik, Panggil $refs.observer.validate() untuk memeriksa validitas form. Saya memiliki objek ini karena saya membungkus form dalam component ValidationObserver dengan ref yang disetel ke obseverver.

Fungsi ini memformat tanggal mulai dan berakhir untuk menyimpan tanggal dan waktu yang benar.

Jika edit prop disetel ke true, panggil fungsi this.editCalendar di requestMixin. Jika tidak, ini disebut this.addCalendar dalam mixin yang sama.

Jika berhasil, ini. Panggil $store.commit (“setEvents”, response.data);. Setelah memanggil this.getCalendar untuk menempatkan event kalender terbaru di Vuex store.

Kemudian emit event eventSaved sehingga Anda dapat menutup modal di beranda Anda.

Selanjutnya, buat direktori mixins dan file requestMixin.js di dalamnya. Tambahkan code berikut.

const APIURL = "http://localhost:3000";
const axios = require("axios");export const requestsMixin = {
  methods: {
    getCalendar() {
      return axios.get(`${APIURL}/calendar`);
    },    addCalendar(data) {
      return axios.post(`${APIURL}/calendar`, data);
    },    editCalendar(data) {
      return axios.put(`${APIURL}/calendar/${data.id}`, data);
    },    deleteCalendar(id) {
      return axios.delete(`${APIURL}/calendar/${id}`);
    }
  }
};

Ini adalah fungsi untuk membuat request HTTP ke backend.

Kemudian modifikasi Home.vue dengan mengganti kode yang ada dengan:

<template>
  <div class="page">
    <div class="buttons">
      <b-button v-b-modal.add-modal>Add Calendar Event</b-button>
    </div>
    <full-calendar :events="events" @event-selected="openEditModal" defaultView="month" /><b-modal id="add-modal" title="Add Calendar Event" hide-footer ref="add-modal">
      <CalendarForm :edit="false" @eventSaved="closeModal()" />
    </b-modal><b-modal id="edit-modal" title="Edit Calendar Event" hide-footer ref="edit-modal">
      <CalendarForm :edit="true" :calendarEvent="calendarEvent" @eventSaved="closeModal()" />
    </b-modal>
  </div>
</template><script>
// @ is an alias to /src
import CalendarForm from "@/components/CalendarForm.vue";
import { requestsMixin } from "../mixins/requestsMixin";export default {
  name: "home",
  components: {
    CalendarForm
  },
  mixins: [requestsMixin],
  computed: {
    events() {
      return this.$store.state.events;
    }
  },
  data() {
    return {
      calendarEvent: {}
    };
  },
  async beforeMount() {
    await this.getEvents();
  },
  methods: {
    async getEvents() {
      const response = await this.getCalendar();
      this.$store.commit("setEvents", response.data);
    },
    closeModal() {
      this.$refs["add-modal"].hide();
      this.$refs["edit-modal"].hide();
      this.calendarEvent = {};
    },
    openEditModal(event) {
      let { id, start, end, title } = event;
      this.calendarEvent = { id, start, end, title };
      this.$refs["edit-modal"].show();
    }
  }
};
</script><style lang="scss" scoped>
.buttons {
  margin-bottom: 10px;
}
</style>

File ini berisi component kalender lengkap dari paket kalender lengkap Vue dan penambahan dan pengeditan modal event kalender. Gunakan CalendarForm untuk keduanya.

Perhatikan bahwa kita sedang menangani eventSaved event yang dikeluarkan oleh CalendarForm. Panggil closeModal saat event diaktifkan sehingga modal ditutup.

Juga, saat membuka modal edit, teruskan calendarEvent dan edit prop disetel ke true.

Referensi modal diatur sehingga Anda dapat menampilkan atau menyembunyikan modal dengan referensi.

Anda bisa mendapatkan status events terbaru di Vuex store dengan melihat $store.state.events.

Kemudian ganti kode di App.vue dengan:

<template>
  <div id="app">
    <b-navbar toggleable="lg" type="dark" variant="info">
      <b-navbar-brand to="/">Calendar App</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 to="/" :active="path  == '/'">Home</b-nav-item>
        </b-navbar-nav>
      </b-collapse>
    </b-navbar>
    <router-view />
  </div>
</template><script>
export default {
  data() {
    return {
      path: this.$route && this.$route.path
    };
  },
  watch: {
    $route(route) {
      this.path = route.path;
    }
  }
};
</script><style lang="scss">
.page {
  padding: 20px;
}
</style>

Tambahkan BootstrapVueb-navbar di sini untuk memantau perubahan routes dan mengizinkan prop aktif disetel ke tautan halaman yang saat ini ditampilkan oleh pengguna.

Kemudian ubah kode di main.js sebagai berikut:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import FullCalendar from "vue-full-calendar";
import BootstrapVue from "bootstrap-vue";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
import 'vue-ctk-date-time-picker/dist/vue-ctk-date-time-picker.css';
import { ValidationProvider, extend, ValidationObserver } from "vee-validate";
import { required } from "vee-validate/dist/rules";
import VueCtkDateTimePicker from 'vue-ctk-date-time-picker';extend("required", required);
Vue.component("ValidationProvider", ValidationProvider);
Vue.component("ValidationObserver", ValidationObserver);
Vue.use(FullCalendar);
Vue.use(BootstrapVue);
Vue.component('VueCtkDateTimePicker', VueCtkDateTimePicker);Vue.config.productionTip = false;new Vue({
  router,
  store,
  render: h => h(App)
}).$mount("#app");

Import semua paket seluruh aplikasi yang digunakan di sini, termasuk BootstrapVue, Vee-Validate, kalender dan widget pemilih tanggal dan waktu.

styles juga diimport di sini sehingga Anda dapat melihatnya di seluruh aplikasi.

Kemudian di router.js, ganti kode yang ada dengan:

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
import 'fullcalendar/dist/fullcalendar.css'Vue.use(Router);export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "home",
      component: Home
    }
  ]
});

Saat pengguna memasukkan URL yang ditentukan atau mengklik tautan ke URL itu, kami mengarahkan aplikasi sehingga pengguna dapat melihat halaman kami.

Kemudian di store.js, ganti kode yang ada dengan:

import Vue from "vue";
import Vuex from "vuex";Vue.use(Vuex);export default new Vuex.Store({
  state: {
    events: []
  },
  mutations: {
    setEvents(state, payload) {
      state.events = payload;
    }
  },
  actions: {}
});

Status event kalender dan ini. Saya menambahkan fungsi setEvents yang dikirim di $store.commit untuk mengatur event di toko dan membuatnya dapat diakses oleh semua component.

Terakhir, ganti kode di index.html dengan:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
    <title>Calendar App</title>
  </head>
  <body>
    <noscript>
      <strong
        >We're sorry but vue-calendar-tutorial-app doesn't work properly without
        JavaScript enabled. Please enable it to continue.</strong
      >
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

Ubah judul aplikasi.

Ini melengkapi semua kerja keras. Cukup gunakan paket NPM server JSON di https://github.com/typicode/json-server untuk backend Anda.

Jalankan perintah berikut untuk menginstal.

npm i -g json-server

Kemudian lakukan hal berikut:

json-server --watch db.json

Di db.json, ganti konten yang ada sebagai berikut:


{
  "calendar": []
}

Kemudian jalankan npm run serve pada command di folder proyek aplikasi Anda untuk menjalankan aplikasi dan menjalankan aplikasi Anda.

Maka Anda akan melihat sesuatu seperti ini: