Vue.js Nedir?

Hobi olarak ilgilendiğim Golang dışında, bu yazıda vakit ayırmaktan oldukça memnun olduğum (dökümanlar ve sunduğu beceriler bağlamında), front-end işlemlerinde kullanılabilecek parlayan bir yıldızdan, bir progressive framework‘ten bahsedeceğim. Son birkaç yıldır hakkıda pek çok yoruma ve yazılmış çeşitli örneklere denk geldiğinizi tahmin ediyorum. Evet, üzerine konuşacağımız framework; Vue.js1.

Vue.js

Vue (Vue.js / VueJS), kullanıcı arayüzleri oluştururken / inşaa ederken kullanılabileceğimiz, Evan You2 tarafından geliştirilen ve duyurulan, açık kaynaklı olarak hayatına devam3 eden bir progressive javascript framework. Progressive framework ile ilgili daha detaylı bir yazı yayınlayacağım. Ancak, şu aşamada bilmeniz gereken en temel konu, progressive framework1 dendiğinde basitliğin ve kendine yeterliliğin öne çıktığıdır. Vue’nun yapısı itibariyle odaklandığı konu, Reactjs4 ve Angular gibi rakiplerine kıyasla çok daha kolay adapte olunabilirliktir. Çekirdek yapısı view katmanına odaklanır (MVVM5 örüntüsünün (pattern) ViewModel katmanına) ve gereksinimler çerçevesinde kolaylıkla harici kütüphanelerle ilişkilendirilebilir. Bu sayede, Vue çekirdeğine entegre edilecek desteklenen kütüphanelerle birlikte hızlı ve kapsamlı single-page uygulamalar (Single Page Applications / SPA) geliştirilebilmektedir6.

Vue ve MVVM yapısı

İşin teknik boyutuna bir geliştirici kadar hakim olamayabilirim. React ve Angular bilgim hiç yok. Bu sebeple teknik karşılaştırma yapmam da pek doğru ve anlamlı olmayacaktır. Buna karşın, öğrenme sürecinde karşılaştığım durumları, “neden?” sorularına bulduğum karşılıkları ve çözümleri aşama aşama ve elbette bir hedefe doğru ilerleyiş üzerinden aktarmaya çalışacağım.

Single-page Application ve Multipage Application karşılaştırması

Kendi deneyimlerim üzerinden aktaracağım ilk durum Vue.js’in reactive yani kullanıcı etkileşimli olması ki bu pek çok framework tarafından da sunulan bir özellik7. React ile yapılan karşılaştırmalarda8 9 öne çıkan ilk husus Vue.js ile CSS, Script ve HTML etiketlerini mustache syntax ({{…}} / yer tutucu) ile tek bir dosya (reusable components / *.vue) olarak yönetebiliyor olmak. Bir diğer husus ise, Vue.js’in de React gibi Virtual DOM üzerinden işlem yapıyor oluşu. Bu sayede, gerçekleştirilen değişiklikler tüm DOM‘un yeniden yürütülmesi yerine DOM karşılaştırması üzerinden sadece ilgili alanlarla sınırlandırılarak yürütülmekte.

Vue.js nezdinde yinelenen ifadeler;

  • Kolay anlaşılabilir ve öğrenilebilir oluşu,
  • Çok yönlü kullanım imkanı,
  • Çekirdek yapısı ve desteklenen kütüphanelerle birlikte sürdürülebilir sonuçlar sağlaması,
  • Hızlı, performanslı ve pratik bir şekilde test edilebilir oluşu.

Vue.js anlatım sürecini framework’ün kendi belgelemesi üzerinden, aynı başlıkları takip ederek ilerleteceğim. Aşağıda, ayrıca değerlendirilebilecek okumalar ve videoları listeledim. Ek sorularınız olursa bulduğum çözümleri yazılara dahil etmekten memnuniyet duyarım.

Kullanım Örneği

Şimdilik tek bir index.html dosyası basit bir Vue.js uygulaması oluşturabilmemiz için yeterli. İlerleyen yazılarda CLI aracılığıyla da nasıl projeler oluşturabileceğimizden bahsedeceğim. Direct <script> Include yöntemiyle geliştirme (development) dosyasını https://vuejs.org/jsvue.js index.html dosyamıza ekleyerek işe koyulalım. HTML sayfamızın ilk hali şu şekilde olsun:

<!DOCTYPE html>
<html>
<head>
 <title>Vue Example #1</title>
</head>
<body>

</body>
</html>

Hızlıca yayınlanan son sürüm üzerinden Vue.js ekleme işlemini gerçekleştirelim ve uygulama alanımızı tanımlayalım. Vue.js dosyasını ayrıca CDN (Örn. https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js ve https://unpkg.com/vue@2.6.10/dist/vue.js) yayınları veya NPM (tavsiye edilen yöntem) aracılığıyla (npm install vue) da edinebilirsiniz. Biz ilk örneklerde vuejs.org yayını üzerinden ilerleyelim.

<!DOCTYPE html>
<html>
<head>
 <title>Vue Example #1</title>
</head>
<body>
<div id="app">
    <h1>{{ message }}</h1>
</div>

<!-- Vue v2.x -->
<script src="https://vuejs.org/js/vue.js"></script>

<!-- Vue v3.x -->
<script src="https://unpkg.com/vue@next"></script>
</body>
</html>

Yukarıdaki index.html dosyasını internet tarayıcınız üzerinden görüntülediğinizde karşınıza h1 etiketleri içerisinde yer alan bir Hello World! mesajı çıkacaktır; binding text. Bu işlemi bir Vue.js uygulaması olarak kurgulayabilmemiz için öncelikle Vue ile etkileşimli alanımızı ilişkilendirmemiz gerekmekte. Aşağıda text binding olarak olarak ifade edilen işleme dair ilk olarak semamtic syntax ve ardından declarative syntax örneklerini görebilirsiniz.

// Vue v2.x
new Vue({
  el: '#app',
  data: {
    message: 'Hello World!'
  }
});

// Vue v3.x
Vue.createApp({
  data() {
    return {
      message: 'Hello World!'
    }
  }
}).mount('#app');

// ya da

const app = {
  data() {
    return {
      message: 'Hello World!'
    }
  }
}

Vue.createApp(app).mount('#app');

el yani element bizim etkileşimli (reactive) alanımızı Vue’ya ilettiğimiz alanımız. data ise key ve value ile ilgili veri işlemleri için direktifleri barındırmakta. app.$el (document.getElementById('ornek')) ile (The View) element olarak tanımlanan HTML etiketini ve vm.$data ile data (The Model) içeriğini çekebilirsiniz.

Hemen index.html dosyamızın içeriğini güncelleyelim.

<!DOCTYPE html>
<html>
 <head>
  <title>Vue Example #1</title>
 </head>
 <body>

  <div id="app">
   <h1>{{ message }}</h1>
   <h1 v-text="message"></h1>
  </div>

  <script src="https://vuejs.org/js/vue.js"></script>

  <script>
  // Vue v2.x
  new Vue({
    el: '#app',
    data: {
      message: 'Hello World!'
    }
  });

  // Vue v3.x
  Vue.createApp({
    data() {
      return {
        message: 'Hello World!'
      }
    }
  }).mount('#app');
  </script>

 </body>
</html>
  • app id değerine sahip bir div var.
  • {{ message }} şeklinde, mustache.js gibi template yapılarından aşina olduğumuz bir ifade (interpolation) oluşturulmuş; semantic syntax.
  • new Vue() instance ve içeriğinde #app id değeri element olarak belirtilmiş.
  • Yine bu instance içerisinde data adlı bir property var ve içeriğindeki message key’i Hello World! değerine (value) sahip. Yani, Vue.js ile kontrol altına aldığımız (#pp) alan içerisindeki değişkenleri ({{…}}) temsil ediyor. Unutmadan, data bir object olduğu için içeriğindeki tanımlamalar (key:value) buna uygun olarak gerçekleştirilmeli. Örneğin key isminde newValue tırnak işaretine gerek olmaksızın yazılabilecek iken new-value tırnak içerisinde tanımlanabilir. Örneklerde bu hususu ayrıca hatırlatacağım.

index.html dosyasını tarayıcınız ile açtığınızda h1 etiketi içerisinde bir önceki görüntülemede de olduğu üzere Hello World! yazacaktır. Ancak, sayfanın kaynak kodunu görüntülediğinizde h1 içeriğinde {{ message }} görünür. Vue.js DOM oluşturulurken belirtilen key’i (message) işaretlendiği alanda bulmuş (#app) ve belirtilen değer ile (Hello World!) değiştirmiştir; declarative rendering. new Vue() instance variable üzerinden de oluşturulabilir.

// Vue v2.x
const app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
});

// Vue v3.x
const app = Vue.createApp({
  data() {
    return {
      message: 'Hello World!'
    }
  }
}).mount('#app');

Bu sayede app.message ile değerlere müdahale edilebilir. Yukarıdaki örneği şu şekilde güncelleyelim.

<!DOCTYPE html>
<html>
 <head>
  <title>Vue Example #1</title>
 </head>
 <body>

  <div id="app">
   <h1>{{ message }}</h1>
  </div>

  <script src="https://vuejs.org/js/vue.js"></script>

  <script>
  // Vue v2.x
  const app = new Vue({
    el: '#app',
    data: {
      message: 'Hello World!'
    }
  });

  // Vue v3.x
  const app = Vue.createApp({
    data() {
      return {
        message: 'Hello World!'
      }
    }
  }).mount('#app');

  //-----
  app.message = 'Bye!';
  </script>

 </body>
</html>

Gördüğünüz üzere ekrana yansıyan Bye! olacaktır. Bunun nedeni, app.message ile {{ message }} için yeni bir değer atamış olmamız. Bu işlemi internet tarayıcınızın (Örn. Chrome) console’u üzerinden de gerçekleştirebilirsiniz.

Vue Console

Örneğimizi biraz daha genişletelim ve bir array içeriğini liste olarak ekrana dökelim. Örneğin, farklı dillerde Selam diyelim10; Tungjatjeta, Salam, Вiтаю, Hola, Hallo, Tere. Bu defa standart HTML kod parçalarını açıklamaya dahil etmeyecek ve parça parça konuyu ele alacağım.

<div id="app">
  <ul>
   <li>{{ message }}</li>
   <li v-text="message"></li>
  </ul>
</div>

h1 etiketini liste ile değiştirdim. Elbette bu bir zorunluluk değil. Farklı HTML etiketlerini kullanabilirsiniz. Önemli olan v-for olarak ifade edeceğimiz işlem neticesinde ilgili etiketin her array değeri için yineleceği. v-for dışında bir de v-bind:title (direktifler) kullanacağım. İlk olarak Vue tanılamamızı şu şekilde yapalım.

// Vue v2.x
const app = new Vue({
  el: '#app',
  data: {
    message: ['Selam', 'Hello', 'Tungjatjeta', 'Salam', 'Вiтаю', 'Hola', 'Hallo', 'Tere']
  }
});

// Vue v3.x
const app = Vue.createApp({
  data() {
    return {
      message: ['Selam', 'Hello', 'Tungjatjeta', 'Salam', 'Вiтаю', 'Hola', 'Hallo', 'Tere']
    }
  }
}).mount('#app');

Bu tanımlamanın çıktısı şu şekilde olacaktır:

[ "Selam", "Hello", "Tungjatjeta", "Salam", "Вiтаю", "Hola", "Hallo", "Tere" ]

Çünkü message ile value ne ise onu gönderdik. Az önce de bahsettiğim üzere v-for ile her tanımı ayrı bir şekilde alabilmekteyiz. O halde li etiketimizi güncelleyelim.

<div id="app">
  <ul>
    <li v-for="msg in message">{{ msg }}</li>
  </ul>
</div>

Yaptığımız değişiklik ile message içeriğinde yer alan ifadeleri sırayla msg adında bir yer tutucuya aktarıyor ve tanımlandığı kodu (li) bu ifadelerle birlikte tekrar uyguluyoruz. Yine yukarıda belirttiğim gibi bir de title kullanımımız var. Bir başka yazıda v-bind konusuna detaylıca değineceğim. Şimdilik sadece ilgili li etiketine title eklemekle yetinelim.

 <div id="app">
  <ul>
    <li v-for="msg in message" v-bind:title="msg">{{ msg }}</li>
  </ul>
</div>

Mouse imlecini ilgili satır üzerine getirdiğinizde msg içeriğinin title attribute içeriğinde de yer aldığını görebilirsiniz.

Vue yazıları boyunca oluşturduğum örnekleri Gitlab > Vue Examples üzerinden edinebilirsiniz edebilirsiniz.

Diğer Yazılar

Bu başlık altından, Vue.js ile ilgili yayınladığım diğer yazılar ve örneklere zaman ve konu sıralamasına göre ulaşabilirsiniz.

Önerdiğim Ücretsiz Kaynaklar