Daha Hafif ve Daha Hızlı - Svelte Çerçevesi İçin Bir Kılavuz

Yayınlanan: 2022-03-11

Web uygulamaları her geçen gün daha popüler hale geliyor. İnsanların basitliği, hızı ve platformlar arası kullanılabilirliği nedeniyle tercih ettiği büyüyen bir dünyadır. Tek Sayfa Uygulamaları (SPA) bu süreçte büyük rol oynadı. Angular, Vue.js ve React gibi çerçeveler, geliştiricilerin kısa sürede en iyi kullanıcı deneyimini sunmalarına yardımcı olur ve kodu desteklenebilir ve genişletilebilir hale getirir. Bu araçlar, yeni oluşturulan paketlere göre birçok avantajla birlikte, uzun süredir sahada en popüler olmaya devam ediyor. SPA dünyasında bir oligopol gibi hissettirdi. Ancak, bu pazarı hedefleyen bir grup ileriye dönük geliştirici ciddi bir rakip olan Svelte ile girebilir.

Svelte, kullanıcı arayüzleri oluşturmaya yönelik yeni bir yaklaşımdır. Gelin ve ortak bir oturum açma formu oluşturarak onu bu kadar yeni yapan şeyin ne olduğunu keşfedelim.

Mimari

Svelte, diğer tüm kitaplıklardan daha hızlı olacak şekilde tasarlanmıştır. Sanal bir DOM oluşturmak için bir çerçeve yükleme adımını değiştirerek ulaşılır. Çalıştırma işlemi sırasında bir araç kullanmak yerine, oluşturma aşamasında Vanilla JS'ye derlenir, böylece uygulamanın başlaması için herhangi bir bağımlılık gerekmez.

ince Diğer SPA kütüphaneleri (React, Vue.js, Angular, vb.)

1. Bir web sitesi açın
2. Sayfayı saf JS kullanarak işleyin

1. Bir web sitesi açın
2. Sanal DOM oluşturma kodu yüklenene kadar bekleyin
3. Kitaplığı kullanarak sayfayı oluşturun

Yukarıdaki tablo, Svelte'nin başlangıç ​​performansında neden mutlak bir kazanan olduğunu açıklamaktadır. Bu, herhangi bir optimizasyonla değil, yan derleyici yerine mevcut tarayıcı JavaScript derleyicisini kullanarak elde edilir.

Kurulum

Svelte kurulumu inanılmaz derecede kolaydır ve kullanımını çok keyifli hale getirir. İlk adım, projenin şablonunu indirmektir:

 npx degit sveltejs/template svelte-login-form

Yukarıdaki komutu tamamlamak, bir Svelte proje şablonuna sahip olduğumuz anlamına gelir. Şu an için boş ve gerekli NPM paketleri henüz kurulmadı. Bunu düzeltelim.

 cd svelte-login-form npm install

Artık uygulama aşağıdaki komutu kullanarak başlamaya hazırdır:

 npm run dev

Yapı

Herhangi bir Svelte bileşeni aşağıdaki bölümleri içerebilir:

  • Senaryo
  • stil
  • Şablon

src/App.svelte dosyasındaki örneğe bakalım.

 <script> export let name; </script> <style> h1 { color: purple; } </style> <h1>{name}</h1>

Yukarıdaki kod tam olarak üç bölüm içerir:

  1. bileşen içinde kullanılması gereken değişkenler ve işlev bildirimleri ile isteğe bağlı bir JavaScript bloğu olan script etiketi.

  2. başka bir isteğe bağlı blok olan style etiketi. Önemli bir fark dışında, yaygın bir HTML stili etiketine çok benzer. Bu blok içinde açıklanan kuralların kapsamı yalnızca bu bileşeni kapsar. Bir p öğesine stil uygulamak, sayfadaki tüm paragrafları etkilemez. Sınıf isimleri bulmanız gerekmediği ve asla yanlışlıkla başka bir kuralı geçersiz kılmayacağınız için bu harika.

  3. Son ve tek gerekli blok bir şablon bloğudur - bu durumda bir h1 etiketi. Bileşeninizin bir sunumu/görünümüdür. Görünümün nasıl şekillendirileceğini ve nasıl davranacağını belirledikleri için stile ve komut dosyası bloklarına sıkı sıkıya bağlıdır.

Svelte, ön uç oyuna modülerlik getirmeye çalışan bir kütüphanedir. Bu modülerliği yalnızca farklı bileşenleri ayırmada değil, aynı zamanda mantığı, görünümü ve şablonu yalıtmada da korur.

Oluşturduğumuz oturum açma formuna dönersek, src klasörünün içinde aşağıdaki içeriğe sahip yeni bir LoginForm.svelte dosyası oluşturalım:

 <style> form { background: #fff; padding: 50px; width: 250px; height: 400px; display: flex; flex-direction: column; justify-content: center; align-items: center; box-shadow: 0px 20px 14px 8px rgba(0, 0, 0, 0.58); } label { margin: 10px 0; align-self: flex-start; font-weight: 500; } input { border: none; border-bottom: 1px solid #ccc; margin-bottom: 20px; transition: all 300ms ease-in-out; width: 100%; } input:focus { outline: 0; border-bottom: 1px solid #666; } button { margin-top: 20px; background: black; color: white; padding: 10px 0; width: 200px; border-radius: 25px; text-transform: uppercase; font-weight: bold; cursor: pointer; transition: all 300ms ease-in-out; } button:hover { transform: translateY(-2.5px); box-shadow: 0px 1px 10px 0px rgba(0, 0, 0, 0.58); } h1 { margin: 10px 20px 30px 20px; font-size: 40px; } </style> <form> <h1></h1> <label>Email</label> <input name="email" placeholder="[email protected]" /> <label>Password</label> <input name="password" type="password" placeholder="password" /> <button type="submit">Log in </button> </form>

Daha sonra daha akıllı hale getireceğimiz aptalca bir tarza sahip bir bileşen. Bu bileşeni sitemizde görmek için onu kök bileşen - App içinde oluşturmalıyız. Gidip src/App.svelte şekilde düzenleyelim:

 <script> import LoginForm from "./LoginForm.svelte"; </script> <style> section { height: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; background: linear-gradient(to right, #cd76e2, #e358ab); } </style> <section> <LoginForm /> </section>

Her şey doğru yapıldıysa ve uygulama hala çalışıyorsa, formumuz localhost:5000 görünecektir. Formu daha akıllı hale getirerek Svelte becerilerimizi geliştirelim.

Durum Bilgisine Geçmek

Svelte'deki herhangi bir bileşenin durumu olabilir. Durum, şablon içinde kullanılabilen özel bir değişken veya bir grup özel değişkendir. Neden "özel" diyorum? Böyle bir değişken değiştirildiğinde, şablon bu konuda bilgilendirilir ve içeriği en yeni duruma getirir. Bu, uygulamanın kullanıcı etkileşimlerine çok hızlı tepki vermesini sağlar.

Uygun alanlar için form değerlerinin saklanacağı email ve password durumu değişkenlerini bildireceğiz. Bu, email ve password değişkenlerimizin her zaman form değerleriyle senkronize olacağı anlamına gelir, bu nedenle, gönderim değerleri ile formdaki gerçek değerler arasında herhangi bir fark olma korkusu olmadan bu değerleri herhangi bir zamanda göndermeye hazır olacağız.

 <script> let email = ""; let password = ""; let isLoading = false; const handleSubmit = () => { isLoading = true; // Simulate network request setTimeout(() => { isLoading = false; // Authorize the user }, 1000); }; </script> <style> /* Style is unchanged */ </style> <form on:submit|preventDefault={handleSubmit}> <h1></h1> <label>Email</label> <input name="email" placeholder="[email protected]" bind:value={email} /> <label>Password</label> <input name="password" type="password" bind:value={password} /> {#if isLoading}Logging in...{:else}Log in {/if} </form>

Durum değişkenleri, genel JavaScript değişkenleri gibi görünürler, ancak onları form değerleriyle senkronize etmek (form alanlarına bağlamak) için bind:value yönergesini kullanmak gerekir. Ayrıca bilinmeyen birkaç şey var:

  • on:submit|preventDefault , varsayılan olayların davranışını önlemenin kısa yoludur. Bu şekilde, her seferinde e.preventDefault() yazmak zorunda kalmaktan daha rahat.

  • {#if isLoading}Logging in...{:else}Log in {/if} , Svelte'nin şablon sözdiziminin bir parçasıdır. Şablon bloğunda JS olmadığı için ifs, döngü vb. kullanmak için özel bir sözdizimi vardır.

Son olarak, formumuza doğrulama eklemek için durumu kullanarak mevcut seçenekleri kullanalım. Form geçersiz değerlerle gönderildiğinde hatalarla doldurulacak olan başka bir durum değişkeni errors oluşturularak elde edilebilir.

 <script> let email = ""; let password = ""; let isLoading = false; let errors = {}; const handleSubmit = () => { errors = {}; if (email.length === 0) { errors.email = "Field should not be empty"; } if (password.length === 0) { errors.password = "Field should not be empty"; } if (Object.keys(errors).length === 0) { isLoading = true; // Simulate network request setTimeout(() => { isLoading = false; // Authorize the user }, 1000); } }; </script> <style> // Previous styles unchanged .errors { list-style-type: none; padding: 10px; margin: 0; border: 2px solid #be6283; color: #be6283; background: rgba(190, 98, 131, 0.3); } </style> <form on:submit|preventDefault={handleSubmit}> <h1></h1> <label>Email</label> <input name="email" placeholder="[email protected]" bind:value={email} /> <label>Password</label> <input name="password" type="password" bind:value={password} /> <button type="submit"> {#if isLoading}Logging in...{:else}Log in {/if} </button> {#if Object.keys(errors).length > 0} <ul class="errors"> {#each Object.keys(errors) as field} <li>{field}: {errors[field]}</li> {/each} </ul> {/if} </form> 
Giriş formu hatası

Form neredeyse tamamlandı. Geriye kalan tek şey, başarılı kimlik doğrulamanın ardından bir başarı mesajıdır.

Başarılı gönderimleri izlemek için varsayılan olarak false olan bir durum değişkeni oluşturalım. Bir formun başarılı bir şekilde gönderilmesinden sonra, bu değişkenin değeri true olarak ayarlanmalıdır.

 let isSuccess = false;

Başarılı bir işlemden sonra isSuccess değiştirme mantığını takip etmek için form gönderimini işleyen fonksiyon da değiştirilmelidir.

 const handleSubmit = () => { errors = {}; if (email.length === 0) { errors.email = "Field should not be empty"; } if (password.length === 0) { errors.password = "Field should not be empty"; } if (Object.keys(errors).length === 0) { isLoading = true; // Simulate network request setTimeout(() => { isLoading = false; isSuccess = true; // Authorize the user }, 1000); } };

Bu değişiklik, gönderim tamamlanır tamamlanmaz formun başarılı durumuna geçmesini sağlar.

Ancak geliştirme sunucunuzu kontrol ederseniz, formun davranışında herhangi bir değişiklik bulamazsınız. Kodu değiştirdik ama henüz şablona dokunmadık. Bir kullanıcı başarıyla oturum açtığında bir başarı mesajı göstermek için şablona talimatlar eklememiz gerekiyor. Svelte'nin şablon sözdizimi bunu kolayca uygulamamıza izin veriyor:

 <form on:submit|preventDefault={handleSubmit}> {#if isSuccess} <div class="success"> <br /> You've been successfully logged in. </div> {:else} <h1></h1> <label>Email</label> <input name="email" placeholder="[email protected]" bind:value={email} /> <label>Password</label> <input name="password" type="password" bind:value={password} /> <button type="submit"> {#if isLoading}Logging in...{:else}Log in {/if} </button> {#if Object.keys(errors).length > 0} <ul class="errors"> {#each Object.keys(errors) as field} <li>{field}: {errors[field]}</li> {/each} </ul> {/if} {/if} </form>

Özelliklerle Özet

Dahili bileşenin durumuyla ilgili her şeyi çözdük. Şimdi, özellikler veya "sahneler" adı verilen dış bağımlılıklardan geçme zamanı. Proplar, bileşene neyin görünmesi gerektiğini veya bileşenin nasıl davranması gerektiğini açıklamak için bileşene iletilen girdiler veya argümanlardır.

Bir özelliğin beyanı, export anahtar sözcüğü dışında duruma benzer.

 <script> export let answer; </script> <p>The answer is {answer}</p>
 <script> import Nested from './Nested.svelte'; </script> <Nested answer={42}/>

Her şey özelliklerle ilgili. Bildirin ve geçin - aksesuarları kullanmak için bilmeniz gereken her şey.

Ancak bu özellikler, oturum açma formu bileşenine nasıl uygulanır? Aksesuarlar, gönderim işlevini bir mülke ayıklayarak oturum açma formumuzu daha genel hale getirebilir. Bu bileşeni, ihtiyacınız olan herhangi bir gönderme işleminde (bir test sunucusuna istek, gerçek bir sunucuya istek, vb.) kullanmanıza izin verecektir. Bu destek, gönder olarak adlandırılacak ve submit eylemi başarılı olursa çözülmüş bir söz ve bir hata varsa reddedilmiş bir söz veren bir işlev olacaktır. Prop'u yukarıda verilen örnekle ilan edelim:

 export let submit;

Oturum açma formunun içindeki gönderim işleyicisi de yeni submit özelliğini kullanacak şekilde düzenlenmelidir.

 const handleSubmit = () => { errors = {}; if (email.length === 0) { errors.email = "Field should not be empty"; } if (password.length === 0) { errors.password = "Field should not be empty"; } if (Object.keys(errors).length === 0) { isLoading = true; submit({ email, password }) .then(() => { isSuccess = true; isLoading = false; }) .catch(err => { errors.server = err; isLoading = false; }); } };

Bileşen hazır görünüyor. Ancak, forma dönüp göndermeyi denerseniz, düğmenin durumunun yüklenmeden değişmediğini fark edeceksiniz. Ayrıca konsolda bir istisna vardır: Uncaught TypeError: submit is not a function . Tabii ki, pervaneyi ilan ettik ama geçmeyi unuttuk. Uygulama bileşeninde bir fonksiyon tanımlayalım ve onu oturum açma formuna iletelim.

 const submit = ({ email, password }) => new Promise((resolve, reject) => setTimeout(resolve, 1000));
 <section> <LoginForm submit={submit} /> </section>

Şimdi form amaçlandığı gibi çalışıyor. Hem hataları gösterebilir hem de girişin başarılı olup olmadığını kullanıcıya bildirebilir.

Giriş formu başarılı

Bağlam Paylaşımı

Bir uygulama oluşturmak için gereken her şey listelenmiş gibi görünüyor. Özellikler ve içsel durumla, gitmeye hazırız. Bu sadece kısmen doğru olsa da. Bu iki genel nokta, yüksek karmaşıklıktaki SPA'ların tasarlanmasını mümkün kılar. Ancak, birçok farklı bileşen arasında veri paylaşmayı denerseniz, bunu çok zor bulacaksınız.

En basit örnek, küresel olarak erişilebilir bir user değişkenine sahip olmaktır. Pek çok bileşen, kullanıcının rolüne, yaşına, durumuna vb. bağlı olarak kullanıcıyla ilgili davranışlarını değiştirmelidir. Ancak, kullanıcıyı sahne kullanarak uygulamadaki her bir bileşene geçirerek kendimizi tekrarlamak KURU DEĞİLDİR.

Svelte'nin bunun için bir çözümü var: bağlam API'si.

Bağlam API'si, bileşenlerin veri ve işlevler arasında aksesuar olarak veya çok sayıda olay göndermeden birbirleriyle 'konuşması' için bir mekanizma sağlar. Gelişmiş bir özellik ama kullanışlı bir özellik.

Kullanıcı bağlamını tasarladığımız oturum açma formuna ekleyelim. Aşağıdaki içeriğe sahip src klasörü içinde bir userContext.js dosyası oluşturun:

 export const key = "userContext"; export const initialValue = null;

Bir uygulama, erişilebilir kalması gereken sınırsız sayıda farklı içeriğe sahip olabileceğinden, key , bağlam için benzersiz bir tanımlayıcıdır. initialValue , ayarlanmadan önceki bağlam için yalnızca varsayılan bir değerdir.

Bir sonraki adım, bağlamı uygulamamıza eklemektir. App.svelte dosyasına gidin ve 2 içe aktarma ifadesi ekleyin:

 import { onMount, setContext } from "svelte"; import { key as userContextKey, initialValue as userContextInitialValue } from "./userContext";

Yukarıdaki koda bakarak svelte paketinden ne aktardığımızı merak edebilirsiniz. onMount , bağımsız değişken olarak bir geri çağırma işlevi gerektiren bir yardımcı işlevdir. Bu geri arama, geçerli bileşen monte edildiğinde (bileşenin yüklenmesinin en başında) yürütülecektir. setContext , bir bağlam için ayarlayıcı bir işlevdir. Bağlamın anahtarını ve argümanları olarak yeni bir değeri gerektirir.

Bağlam için varsayılan değeri ayarlamak için onMount işlevini kullanalım:

 onMount(() => { setContext(userContextKey, userContextInitialValue); });

Ve kullanıcı bağlamını ayarlamak için submit işlevini değiştirin:

 const submit = ({ email, password }) => new Promise((resolve, reject) => { setTimeout(() => { setContext(userContextKey, { name: "Foo", lastName: "Bar", email: "[email protected]" }); resolve(); }, 1000); });

Bu kadar. Başarılı bir gönderim, kullanıcı bağlamını, bir bağlam alıcısı getContext tarafından erişilebilen sahte bir kullanıcı nesnesine değiştirir:

 <script> import { getContext } from 'svelte'; import { key as userContextKey } from "./userContext"; const user = getContext(key); </script>

Özet

Svelte, yüksek performanslı ve esnek bir API'ye sahip güçlü bir araçtır. Bu gönderide ele alınan temel bilgilerin yanı sıra Svelte, kutudan çıktığı haliyle aşağıdaki özelliklere sahiptir:

  • Reaktif bildirimler ve ifadeler
  • Şablon bloklarını bekleyin
  • Boyut bağlama
  • Redux gibi küresel bir mağaza
  • Animasyon ve geçiş yardımcıları
  • Hata ayıklama yardımcısı

Özetlemek gerekirse, Svelte, SPA'lar oluşturmak için tüm ihtiyaçları ve daha fazlasını karşılayan harika bir kütüphanedir. Piyasadaki en büyük oyuncularla rekabet edebilir ve hatta kazanabilir. Bununla birlikte, şu anda kullanabileceği şey, ön uç geliştiriciler topluluğundaki destektir.

Not: Bu makaledeki tüm teimurjan/svelte-login-form GitHub deposunda bulunabilir. Giriş formunun demosuna buradan ulaşabilirsiniz.