Kişisel VueJs Dökümanım

Kişisel VueJs Dökümanım

Sefa Çiçekli / sefacicekli.com

Slot

Slotlar bir component'den başka bir component'e content göndermek için kullanılır.

Kullanımı

Parent'dan Child'e content (herhangi bir html elementi vb. olabilir) gönderirken:

<template>
  <div>
    <child-component>
      <h5>Merhaba!</h5>
      <a href="google.com">Google'a gitmek için tıkla</a>
    </child-component>
  <div>
</template>

Parent.vue

<template>
  <slot></slot>
</template>

ChildComponent.vue

Bu durumda ise Parent'da belirttiğimiz tüm içerik ekleniyor. Peki ya biz slotlara ad verip ayrı ayrı alsak ne olur?

Aşağıdaki örnekteki gibi:

<template>
  <div>
    <child-component>
      <h5 slot="heading">Merhaba!</h5>
      <a slot="link" href="google.com">Google'a gitmek için tıkla</a>
    </child-component>
  <div>
</template>

Parent.vue

<template>
  <div>
     <slot name="heading"></slot>
  </div>
  <div>
     <slot name="link"></slot>
  </div>
</template>

ChildComponent.vue

Bu şekilde istediğimiz slot'u istediğimiz yerde çağırabiliriz.


Input Modifiers

Input Modifier'lar inputlarda girilecek değeri kontrol etmek için kullanır.

Örneğin girilecek değerin lazy şeklinde çıktı vermesini sağlayabiliriz.

Örnek:

<template>
  <div>
     <input type="number"
       id="age"
       class="form-control"
       v-model.lazy="userData.password">
  </div>
</template>


Burda input'a v-model ile lazy özelliğini koyduğumuzda userData.password data'sıne veri ancak input'daki focus'umuz kaybolduğunda aktarılacak.

Örnek olarak trim, number gibi modifierlar da kullanılabilir.

Daha fazla bilgi için tıkla

Custom Directivelar

Global Tanımlama

Global olarak bir directive tanımlamak için app.js dosyasına (vue instance nerede oluşturulmuşsa) bunu belirtmemiz gerekiyor.

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

Vue.directive("italic", {
  bind(el, binding, vnode){
    el.style.font-style = 'italic'
  }
});

new Vue({
  el: '#app',
  render: h => h(App)
})

Burdaki italic argümanı directive'in adını belirliyor. Bu directive ile eklenen elementteki yazı tipini italik olarak ayarladım.


Filters

Filters özelliği data'daki propertylere filtre uygulamamız gereken durumlarda kullanılır. Bu veriler sadece kullanıcıya görünen tarafta değişir. Verinin kendisi değişmez.

Örnek:

<template>
  <div>
    <div> {{ message | toUpper }}
  </div>
</template>


<script>
export default {
  data: {
    return {
      message: "Around the World"
    }
  }
  filters: {
    toUpper(value){
      return value.toUpperCase();
    }
  }
};
</script>


Birden fazla kullanmak istiyorsak | işaretini tekrar kullanarak zincirleme şeklinde uygulayabiliriz.

Önemli Not: Çoğu zaman Filters kullanmak yerine Computed kullanmak daha mantıklıdır. Filters veriyi manipüle etmek için dom'u sürekli render eder. Verinin orijinali değişmeksizin bu durum fark etmez. Ancak Computed sadece orijinal data'daki veri değişince re-render eder.

Mixins

Mixin'ler VueJs'in en iyi özelliklerinden biridir ve oldukça kullanışlıdır. Genelde filter'ı kullanmanın pek mantıklı olmayacağı veya componentler arası birden fazla filtre işlemi yapmamız gereken durumlarda kullanılır.

Burada yapmamız gereken istediğimiz filtre vb. işlemini ayrı bir js dosyasında yazmak ve kullanacağımız vue component'inde import etmek.

Örnek: tıkla

Detaylı Bilgi için tıkla.


Transition

Aslında Vue'de animasyon işlemleri için ayrı bir yazı hazırlamayı düşünüyordum. Ancak şimdilik burada da kalabilir. İleriki zamanlarda taşıyabilirim.


Vue'de animasyonlar yapmak çok basit.

Öncelikle istediğimiz animasyonun tipini bir etiketmiş gibi tanımlıyoruz. Sonra da bu animasyon için css kodunu yazacağımız bir ad belirliyoruz. Örneğin fade, test, deneme vb. herhangi bir şey olabilir.

Style kısmında VueJs bizden bu animasyon işlemi için ona 4 tane class göndermemizi bekliyor. Örneğin fade adını belirledik. CSS sınıflarının isimleri de sırasıyla şöyle olmalı:

  • .fade-enter
  • .fade-enter-active
  • .fade-leave
  • .fade-leave-active

Aşağıdaki örnekten konuyu çok daha iyi anlayabiliriz.

Örnek için tıkla

Sonucu görüntülemek için tıkla

a) onLoad ile animasyon tetikleme

Tetikleme işlemini illaki butonlar ile yapacağız diye bir kaide yok. Sayfa açılınca tetikleme istiyorsak appears attribute'unu eklememiz yeterli.

b) Diğer css sınıflarını VueJs transition ile birlikte kullanma

Örneğin animate.css animasyonlarını vueJs ile birlikte kullanabilir miyiz? Evet.

VueJs buna benzer işlemler için bize epey kolaylık sağlıyor. Fakat normale göre bu sefer Vue'nin tanıdığı css sınıflarını attribute olarak gönderiyoruz:

  • enter-class
  • enter-active-class
  • leave-class
  • leave-active-class

Örnek kullanım için tıkla.

Sonucu görüntülemek için tıkla.

c) Birden fazla elemente transition uygulamak

Bazen bir element kaybolurken yerine başka bir element'in gelmesini isteyebiliriz. Bu tarz geçişlerde Vue'nin bu elementlerin farklı elementler olduğunu anlamasını sağlamak için key attribute'unu kullanırız.

Bu işlem için farklı farklı modlar bulunuyor. Aşağıdaki örnekte out-in modunu kullandım. Yani bir element görünmez olacakken diğeri görünür olacak.


Örnek için tıkla.

Sonucu görüntülemek için tıkla.

d) Javascript ile animasyon uygulama

Üstteki animasyon işlemlerinde hep css classları kullanmıştık. Peki acaba VueJs arkada bunları nasıl çalıştırıyor?

VueJs bunlar için 8 farklı metod kullanıyor:

  • before-enter
  • enter
  • after-enter
  • after-enter-cancelled
  • before-leave
  • leave
  • after-leave
  • after-leave-cancelled

Bu Vue hooklarını kullanabilmek için metodları belirtmemiz gerekiyor.

enter ve leave metodları iki parametreye sahiptir: el ve done.

el, elementin kendisini verirken done da bitirmek için kullanılır.

Aşağıdaki örnekte kullanımlarını görebilirsiniz.

Not: :css="false" gibi bir kullanım fark etmiş olabilirsiniz. Bu bind işlemini performans açısından false yaptım. Zira VueJs ile transition kullanıp name belirtmediğim sürece VueJs benden css kodu bekleyecek. Bunun önüne geçmek için de bind işlemini false yaptım.

Örnek için tıkla.

Sonucu görüntülemek için tıkla.


e) transition-group ile liste elemanlarına animasyon uygulama

Liste elemanları gibi birçok elemente animasyon uygulamak için transition-group elementini kullanırız.

Kullanımı transition ile tamamen aynıdır. Sadece ek olarak yeni element ekleme vb. işlemler için move css class'ını da kullanırız.

Ek olarak Vue'nin bunların ayrı elementler olduğunu bilmesi için key attribute'unu da belirtmemiz gerekiyor.

Örnek için tıkla.

Sonucu görüntülemek için tıkla.


Router

VueJs'de SPA'nın gücünü sonuna kadar kullanmamızı sağlayan bir yapıya hoş geldik.

VueJs ile Router işlemlerini gerçekleştirmek için Vue-Router paketine ihtiyacımız var.

npm install --save vue-router

komutu ile paketi kurabiliriz.

VueJs'e dâhil etmek için de main.js dosyasında instance içerisinde tanımlamalıyız.

Vue 2 için aşağıdaki şekilde tanımlarız:

import Vue from 'vue'
import App from './App.vue'
import VueRouter from "vue-router";
import { routes} from "./routes";

Vue.config.productionTip = false

Vue.use(VueRouter);

new Vue({
  render: h => h(App)
}).$mount('#app')

Routerları farklı bir js dosyası ile kullanabilmek için router.js adlı bir kod dosyası oluşturalım.

Gerekli olan componentleri kullanabilmek için yine tanımlamamız lazım.

import Home from "./components/Home";
import About from "./components/About";
import User from "./components/User";

Routerları dışarıdan kullanabilmek için de export ile belirtmemiz lazım. Routerlar için objenin dönmesi gerekiyor.

export const routes = [
    {path: '', component: Home, name: "home"},
    {path: '/about', component: About}
]

Buradaki path, URL'de hangi parametre girilirse hangi component'in görüneceğini belirtiyor. Name ise bu router için anahtar kelime diyebiliriz. Başka bir yerde bu route'ı kullanmamız gerekirse name'i yazmamız yeterli olacaktır.


Instance'a geri dönelim. Route.js dosyasında girdiğimiz routeları VueJs'e tanımlamamız gerekiyor. Bunun için aşağıdaki gibi bir yapı kullanabiliriz.

const router = new VueRouter({
  routes,
  mode: 'history'
})

Burada istersek routes yerine kendimiz de yerel olarak route belirtebiliriz. Ama biz farklı bir dosya kullanmayı tercih ettik.

Mode, link yapısının nasıl olacağını ayarlar. history ve hash olmak üzere iki çeşittir. hash modunda link yapısında router'dan önce # işaretini yazar. history modunda bunu kullanmaz.

Instance'ı güncelleyelim:

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

Son durumda dosya ağaç yapısı şu şekilde oluyor:

components/
├─ About.vue
├─ Header.vue
├─ Home.vue
App.vue
main.js
routes.js

Route işlemine göre hangi linkte hangi component'in görüneceğini router-view aracılığı ile yapabiliriz.

App.vue içerisinde kullanalım

<template>
  <div id="app">
    <router-view></router-view>
    <Header></Header>
  </div>
</template>

<script>
import Header from "./components/Header";
export default {
  name: 'App',
  components: {
    Header 
  }
}
</script>

router-view kullanarak o kod bloğuna istenilen componentin getirilmesini sağlıyoruz.

Burada header dosyasını import etmemiz yeterli. Header içerisinde diğer componentleri kullanacağız.

Amacımız header'ı menü gibi kullanıp tıklanma durumlarına göre App.vue'deki router-view'i kullanarak componentler arası geçiş yapmak.

router-link yapı olarak aslında bir HTML etiketidir.

router-link'i kullanırken duruma göre 4 parametreye ihtiyaç duyarız.

active-class, linkin aktif olduğu durumda stillendirme işlemi için class vermemize olanak sağlarken to da linkin nereye gideceğini belirtir. tag ise hangi elementin yerine geçeceğini ayarlar. Örneğin parent elemente ul verip router-link'e li verebiliriz.

Son parametre ise exact. exact hangi linkin seçili olduğunu bize gösterir.

<template>
  <div>
    <router-link
        active-class="selected"
        exact
        to="/">
      <a>Home</a>
    </router-link>
    <router-link
        active-class="selected"
        to="/about">
      <a>About</a>
    </router-link>
  </div>
</template>
//Header.vue dosyası

Dinamik link kullanmak

Vue Router ile sadece statik çağrıları almayız, değişen şink yapılarını da alabiliriz. Örneğin sefacicekli.com/user/45 şeklindeki bir linkte amele gibi tek tek sayıları route dosyasında belirtmeyiz. Bunun için id yapısını kullanırız.

export const routes = [
    {path: '', component: Home, name: "home"},
    {path: '/about', component: About},
    {path: '/user/:id', component: User},
]

Bu şekilde bir yapıda id dinamik olan kısımı alır ve componentler içerisinde bu veriyi kullanırız.

User component'inde id değerini almak için

$route.params.id

kodunu kullanırız.

Not: Bazı durumlarda componentler tekrar create edilmeye ihtiyaç duymaz. Bu yüzden de almak istediğimiz değer yanlış olabilir. Bunun önüne geçmek için watch kullanmalıyız.

watch: {
  "$route"(to, from){
    this.id = to.params.id;
  }
}