Vue CLI ve Örnek REST API Uygulaması

Vue.JS ile ilgili anlatımların ardından artık bu anlatımları örneklerle pekiştirmenin zamanı geldi.

AA

Son olarak yayınladığım Vue.js Single-File JavaScript Components ve Vue Kurulum ve Kullanım Yöntemleri yazılarını da pekiştirmek amacıyla Vue CLI ile temel bir proje oluşturup, bu projenin içeriğinde JSONPlaceholder tarafından sunulan verilere fetch() ile erişecek ve elde ettiğimiz verileri listeleyeceğiz1. O halde, hızlı bir şekilde başlayalım ve Vue CLI kurulumumuzu (bkz. Yarn) yapalım.

Vue CLI Kurulumu ve Proje Oluşturma

npm install -g @vue/cli
# YA DA
yarn global add @vue/cli

vue create vue-rest-api-jsonplaceholder

Herhangi bir ek yapılandırma olmaksızın kurulum işlemini tamamladım. Elbette bu işlemi Vue UI arayüzü aracılığıyla da gerçekleştirebilirsiniz. Şimdilik terminal aracılığıyla ilerlemeye devam edelim.

  • Manually select features
    • Babel ve Linter/formatter seçili.
    • ESLint with error prevention only seçili.
    • Lint on save seçili.
    • In dedicated config files seçili.
  • Ayarları bir sonraki proje için saklamadım ve kurulumu başlattım.

Yaklaşık ~45 saniyelik kurulum işleminin ardından projeyi oluşturduğum dizinde, belirttiğim isimde (vue-rest-api-jsonplaceholder) ~165 MB‘lık bir içerik oluşturuldu. Elbette bu dosya boyutunun çoğu node_modules‘e ait. Oluşturulan bu dizinde çalışmaya başlamak için şu yolları izlememiz yeterli.

Vue Create Komutu
cd vue-rest-api-jsonplaceholder
# YARN İÇİN
yarn serve

#NPM İÇİN
npm run serve

serve komutunun ardından localhost üzerinden belirtilen port aracılığıyla (Örn. 8080) oluşturulan şablon uygulamayı görüntüleyebiliriz. Bu şablon aynı zamanda kurulum aşamasındaki seçimlerinizin de bir dökümü olarak nitelendirilebilir. Aşağıdaki görselde terminal ekranındaki seçimlerimiz (babel ve eslint) de dahil olmak üzere çeşitli bilgilerin ve bağlantıların listelendiğini görebilirsiniz.

Vue Create - Preview

Başlangıç olarak, işlemlerimizin çoğunu src alt klasöründe (main.js ve App.vue ile) gerçekleştireceğimizi ekleyeyim. Components klasörü içeriğindeki HelloWorld.vue component’ini silebiliriz. Tabi, bu silme işleminin ardından App.vue içeriğindeki import işlemini ve components object içeriğindeki component tanımını da kaldırmamız gerekir. Son durumda, App.vue içeriğimiz şu şekilde olacak.

<template>
  <div id="app"></div>
</template>

<script>

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

<style></style>

main.js içeriğimizi de şu şekilde düzenleyebiliriz:

import Vue from 'vue'
import App from './App.vue'

// Vue v2.x
new Vue({
  render: h => h(App),
}).$mount('#app');

// Vue v3.x
Vue.createApp({
  render: h => h(App),
}).mount('#app');

Bu süreçte bir yazım hatası olması durumunda terminal ekranında çeşitli uyarılarla karşılaşabilirsiniz. Örneğin, arasına // eklemesini yapalım. Bu durumda şöyle bir uyarı dönecektir. Hataya neden olan eklemeyi kaldırım kaldığımız yerden devam edelim.

Vue Fetch İle Veri Çekmek

Bir sonraki işlemimiz JSONPlaceholder üzerinden sunulan örnek verilere erişmek. Örneğin, posts içeriğini örneğimizde kullanabiliriz. Bu işlemi fetch ile (normalde axios kullanmayı tercih ediyorum) gerçekleştireceğim.

fetch('https://jsonplaceholder.typicode.com/posts')
  .then(response => response.json())
  .then(json => console.log(json))

fetch işlemini App.vue dosyası içerisinde method olarak oluşturup, Vue lifecycle'ın create() aşamasında çağıracağım2.

<template>
  <div id="app">
    <ul>{{ message }}</p>
  </div>
</template>

<script>

export default {
  name: 'app',
  data() {
    return {
      message: 'Hello World!'
    }
  },
  components: {
  },
  methods:{
    fetchSomeData(){
      fetch('https://jsonplaceholder.typicode.com/posts', {
        method: 'GET'
      })
      .then(response => response.json())
      .then(json => this.message = json)
    }
  },
  created(){
    this.fetchSomeData()
  }
}
</script>

<style></style>

Component’in çalışmasının ardından, daha önce Hello World! içeriğine sahip olan message fetchSomeData() ile çektiğimiz verileri ekrana dökecektir. Şimdi div#app içeriğinde bir liste oluşturalım ve bu verileri v-for direktifi ile daha düzenli bir şekilde görüntüleyelim.

  <div id="app">
    <ul>
      <li v-for="(user, index) in message" :key="'user'+user.userId+'-'+index">
        {{ user }}
      </li>
    </ul>
  </div>

Evet, user içeriğimiz biraz daha okunabilir bir hale geldi. Arayüzü biraz daha düzenlemek istersek style etiketi içerisinde listeyi yeniden ele alabiliriz. Ancak, ben daha kapsamlı bir çözüm olarak Bulma CSS kullanacağım.

Bulma CSS Components ve Buefy

Bu işlemi doğrudan CDN aracılığıyla (standalone) ilgili dosyaları ekleyerek gerçekleştirebilirim. Daha önce pek çok örnekte bu yolu izlemiştik. O halde, işleri biraz daha ileriye götürelim ve buefy3 kullanalım.

Uygulamamızı geliştirdiğimiz dizin (ben vue-rest-api-jsonplaceholder adını tercih etmiştim) içerisinden npm veya yarn ile ilgili component’i çağırabiliriz.

npm install buefy
yarn add buefy

Kurulumun ardından buefy’i nasıl entegre etmek istediğimize karar vermeliyiz. Full bundle tercihi ile Bulma CSS’in tüm özelliklerini çalışmamızda kullanabiliriz.

import Vue from 'vue'
import Buefy from 'buefy'
import 'buefy/dist/buefy.css'

Vue.use(Buefy)

Ancak, ilgili örneğimizde tüm özelliklerimize ihtiyaç duymuyoruz. Bulma dahilindeki component‘leri ayrı ayrı çağırabiliriz. Bu işlemi plugin (individual components as Vue plugins) ve/veya ayrı component’ler (individual components) olarak yapabiliriz. Ben listeleme işlemini user içeriğini daha net görüntüleyebilmek adına table ile işlemek istiyorum.

import Vue from 'vue'
import Table from 'buefy/dist/components/table'
import 'buefy/dist/buefy.css'

Vue.use(Table)

// ya da

import Vue from 'vue'
import { Table } from 'buefy/dist/components/table'
import 'buefy/dist/buefy.css'

Vue.component('b-table', Table)

Şimdilik plugin kullanımı (Vue.use(Table)) ile devam edelim ve main.js ile App.vue dosyalarımızın içeriklerini buna kararlarımız doğrultusunda düzenleyelim. Son durumda main.js içeriğimiz şu şekilde olacak.

import Vue from "vue";
import App from "./App.vue";
import Table from "buefy/dist/components/table";
import "buefy/dist/buefy.css";

Vue.use(Table);

// Vue v2.x
new Vue({
  render: h => h(App)
}).$mount("#app");

// Vue v3.x
Vue.createApp({
  data() {
    return { count: 1 }
  }
}).mount('#app');

Görüldüğü üzere import ile ilgili Bulma component’ini çağırdık ve Vue.use() ile uygulamamız içerisinde işleme aldık. Son durumda App.vue içeriğimiz de şu hale geldi:

<template>
  <div id="app">
    <div class="container">
    <b-table :data="message" focusable>
      <template slot-scope="props">
        <b-table-column field="id" label="ID" width="40" numeric>{{ props.row.id }}</b-table-column>
        <b-table-column field="title" label="Title">{{ props.row.title }}</b-table-column>
        <b-table-column field="body" label="Body">{{ props.row.body }}</b-table-column>
      </template>
      <template slot="empty">
        <section class="section">
          <div class="content has-text-grey has-text-centered">
            <p>Nothing here.</p>
          </div>
        </section>
      </template>
    </b-table>
    </div>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: []
    }
  },
  components: {
  },
  methods:{
    fetchSomeData(){
      fetch('https://jsonplaceholder.typicode.com/posts', {
        method: 'GET'
      })
      .then(response => response.json())
      .then(json => this.message = json)
    }
  },
  created(){
    this.fetchSomeData()
  }
}
</script>

v-bind direktifi ile message içeriğini doğrudan tablo satırları haline getirebilmekte ve props.row ile kullanabilmekteyiz. Geri kalan tüm işlem artık Buefy ile sağlanmakta. Bu tablo işlemini daha basit bir şekilde ele almaya ne dersiniz? Mesela, sütun tanımlarını bir nesne içerisinde tanımlayalım ve tabloda bu sütunları kullanalım.

<template>
  <div id="app">
    <div class="container">
      <b-table :data="message" :columns="columns"></b-table>
    </div>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      message: [],
      columns: [
        {
          field: 'id',
          label: 'ID'
        },
        {
          field: 'title',
          label: 'Title',
        },
        {
          field: 'body',
          label: 'Last Name',
        }
      ]
    }
  },
  components: {
  },
  methods:{
    fetchSomeData(){
      fetch('https://jsonplaceholder.typicode.com/posts', {
        method: 'GET'
      })
    .then(response => response.json())
    .then(json => this.message = json)
  }
  },
  created(){
    this.fetchSomeData()
  }
}
</script>

Evet, işlemlerimiz bu kadar. Görüldüğü üzere kolaylıkla basit bir şekilde API ile veri çekip, çektiğimiz bu verileri Buefy aracılığıyla sade bir tablo olarak ekrana döktük. Buefy Table sayfasını inceleyerek oluşturulan tabloyu istediğiniz şekilde özelleştirebilirsiniz.