VueJs-#08a Vuex State

Pengenalan

Vuex adalah library Vue.js yang dapat digunakan untuk meng-handle state (state manajemen), dimana data yang ada dapat didefinisikan dan dipusatkan pada sebuah file sehingga bisa digunakan oleh semua component yang ada.

Dengan menggunakan Vuex, komunikasi antar component menjadi lebih mudah. Sebagaimana yang kita ketahui bahwasanya dalam interaksi antar component agar dapat saling bertukar data adalah dengan menggunakan props, maka dengan Vuex kamu cukup mengakses state yang telah didefinisikan pada Vuex Store.

Persiapan

Artikel ini merupakan bagian pertama, maka kita memulainya dengan project yang masih fresh installInstall Vue.js dengan menggunakan vue cli:

vue create vue-bootstrap-vuex

Pilih enable options router & vuex

Sehingga Struktur direktorinya menjadi seperti gambar di bawah ini :

vue with router, vuex, & bootstrap

Perhatikan gambar di atas pada folder src terdapat file-file bawaan options penginstallan router & vuex :

  • router.js, file ini berfunsi untuk mendefinisikan router2 berdasarkan komponen, dibuat otomatis karena kita menyertakan options vue-router
  • store.js, file ini berisi state vuex dibuat otomatis karena kita menyertakan options vuex
  • views, folder ini berisi template views untuk komponen dibuat otomatis karena kita menyertakan options vue-router

Setelah selesai untuk mempercantik tampilan kita menggunakan theme bootstrap Install bootstrapVue

vue add bootstrap-vue

Sekarang kita ubah src/App.vue

<template>
  <div id="app">
    <div>
      <b-navbar toggleable="lg" type="dark" variant="info">
        <b-navbar-brand href="#">NavBar</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="/">Home</b-nav-item>
            <b-nav-item to="About">About</b-nav-item>
            <b-nav-item to="#" disabled>Disabled</b-nav-item>
          </b-navbar-nav>
     
          <!-- Right aligned nav items -->
          <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>
              <!-- Using 'button-content' slot -->
              <template v-slot: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>
    <div class="container mt-2">
      <router-view></router-view>
    </div>
  </div>
  <!--<div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view />
  </div>-->
</template>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

Jalankan service vue:

npm run serve
Tampilan dengan Bootstrap

Manajemen State Dengan Vuex

Tambahkan Menu baru pada src/App.vue

<template>
  <div id="app">
    <div>
      <b-navbar toggleable="lg" type="dark" variant="info">
        <b-navbar-brand href="#">NavBar</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="/">Home</b-nav-item>
            <b-nav-item to="About">About</b-nav-item>
            <b-nav-item to="LearningVuex">Learning Vuex</b-nav-item>
            <b-nav-item to="#" disabled>Disabled</b-nav-item>
          </b-navbar-nav>

          <!-- Right aligned nav items -->
          <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>
              <!-- Using 'button-content' slot -->
              <template v-slot: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>
    <div class="container mt-2">
      <router-view/>
    </div>
  </div>
</template>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
</style>

Siapkan route “Learning Vuex” di src/router.js

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";

Vue.use(Router);

export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "home",
      component: Home
    },
    {
      path: "/about",
      name: "about",
      // route level code-splitting
      // this generates a separate chunk (about.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () =>
        import(/* webpackChunkName: "about" */ "./views/About.vue")
    },
    {
      path: "/learningvuex",
      name: "LearningVuex",
      component: () =>
        import("./views/LearningVuex.vue")
    }
  ]
});

Buka file src/store.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
      agenda: [
        { hari: 'Senin', kegiatan: 'Belajar Vuejs' },
        { hari: 'Selasa', kegiatan: 'Belajar Laravel' },
        { hari: 'Rabu', kegiatan: 'Belajar Mysql' }
      ],
  },
  mutations: {},
  actions: {}
});

Sekarang kita akan membuat Component memanggil state di atas:

Membuat Page Views LearningVuex.vue untuk memanggil kedua Component

<template>
	<div id="app" class="container">
		<div class="row py-4">
			<agenda-show post-title="Daftar Agenda"/>
		</div>
	</div>
</template>

<script>
	import AgendaShow from '../components/AgendaShow.vue'

	export default {
		name: 'app',
		components: {
			AgendaShow
		}
	}
</script>

Membuat Component :

src/components/AgendaShow.vue

<template>
    <div class="col-md-6">
        <div class="card">
            <div class="card-header">
                <h3 class="card-title">{{postTitle}}</h3>
            </div>
            <div class="card-body">
                <div class="table-responsive">
                    <table class="table table-hover table-bordered">
                        <thead>
                            <tr>
                                <th>#</th>
                                <th>Hari</th>
                                <th>Agenda</th>
                                <th></th>
                            </tr>
                        </thead>
                        <tbody>
                            <!-- Memanggil state agenda dari STORE -->
                            <tr v-for="(row, index) in this.$store.state.agenda" :key="index">
                                <td>{{ index+1 }}</td>
                                <td>{{ row.hari }}</td>
                                <td>{{ row.kegiatan }}</td>
                                <td></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
    export default {
        name: 'AgendaShow',
        props: ['postTitle'],
    }
</script>

Buka kembali browser http://localhost:8080

Table Agenda

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>