見出し画像

【IT】Svelte入門

皆さま
こんにちは

今日は、「Svelte」について学習します。

「Svelte」は、高速、軽量なJavaScriptのフレームワークとなります。

State of JavaScriptでも人気が高まりつつあるようです。


1.前提条件

nodeとnpm がインストールされていることを前提しております。
以下は、今回の環境です。(PCは、M1 Macを使用しております)

$ node -v
v22.12.0

$ npm -v
11.0.0

インストールされていない場合は、以下でインストールします。
(Macでの説明となります)

# nodeのインストール
$ brew install nodebrew
nodebrew setup

$ echo "# Nodebrew" >>  ~/.bash_profile
$ echo "export PATH=$HOME/.nodebrew/current/bin:$PATH" >>  ~/.bash_profile
$ source  ~/.bash_profile
 
# 今回は、Nodeは、22.12.0をインストールします。
$ nodebrew install v22.12.0
$ nodebrew use v22.12.0
 
# npmのインストール
$ npm install -g npm

2.Svelteのインストール

以下のコマンドでインストールします。
今回は、Svelte単体をJavaScriptを選択します。

$ npm create vite@latest

> npx
> create-vite

✔ Project name: … test-web001
✔ Select a framework: › Svelte
✔ Select a variant: › JavaScript

Scaffolding project in /Users/test-user/Svelte/test-web001...

Done. Now run:

  cd test-web001
  npm install
  npm run dev

Done. Now run:

  cd vite-project
  npm install
  npm run dev

$ cd vite-project
$ npm install

added 35 packages, and audited 36 packages in 15s

3 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

$ npm run dev

> vite-project@0.0.0 dev
> vite

Forced re-optimization of dependencies

  VITE v6.0.7  ready in 445 ms

  ➜  Local:   http://localhost:5173/Network: use --host to expose
  ➜  press h + enter to show help

3.お天気APIの利用登録

今回は、お天気APIをSvelteから利用しますので事前に登録します。

今回は、「OpenWeather」を利用させて頂きます。

Open Weather Mapは、有料版もありますが、無料版でも
1分間に60リクエストかつ1ヶ月100万リクエストが可能で個人利用には十分な性能です。

登録してAPIキーを取得します。

ブラウザーで取得したAPIで得られる情報を確認します。
今回使用するAPIの情報を確認します。
国、気温(°c)、都市名、アイコン情報

4.Svelteのクリーンアップ

src/app.cssは空に
src/lib/Counter.svelteは削除します。

src/App.svelteは、元々のコードを削除して以下の通りとします。

// App.svelte

<script>
  import "./assets/base.css";
  import axios from "axios";

</script>

<main>
  <div class="wrapper">
    <div class="container">
	  <h1>Web Test</h1>
	</div>
  </div>
</main>

<style>

</style>

src/assetsに背景用画像を配置します。(jpg)
今回は、background_img.jpg

src/assets/base.cssを空で作成します。
後ほど追記します。

APIリスクエスト用にaxiosも入れておきます。

  npm install axios

src/assets/base.cssに簡単なCSSを追記します。
定義追加、修正ください。

#一部抜粋
/* base.css */

@import url("https://fonts.googleapis.com/css2?family=Sixtyfour&display=swap");

body {
  font-family: "Sixtyfour", sans-serif;
  font-weight: 400;
  font-size: 1.1rem;
  font-display: swap;
  color: rgb(26, 190, 29);
  margin: 0;
  padding: 0;
}

/* App.Svelte */
.wrapper {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center; 
  background: url("./background_img.jpg") center center no-repeat;
  background-size: cover;
}
.container {
  width: 50vw;
  text-align: center;
・
・
・

5.今回の構成(サブコンポート)

今回は、シングルページ構成として
4つのサブコンポーネントから構成するものとします。

・Title
・Form
・Results
・Loading

各ファイルは、
src/lib配下に作成します。

・Title
タイトル画面を表するだけのコンポートです。
(HTMLのみ構成となります)

#一部抜粋
// Title.svelte
・
・
・
<main>
  <h1>Svelte Wether</h1>
</main>
・
・
・

・Form
検索する都市名を取得します。
createEventDispatcher関数は、Svelte5から非推奨となりましたので
親(App.svelte)から渡される関数をプロパティとして受け取る形とします。

#一部抜粋 
// From.svelte

<script>
  export let onSubmitForm; // 親から渡される関数をプロパティとして受け取る
  let city = ""; 

  const submitForm = (event) => {
    event.preventDefault();
    onSubmitForm(city); // 親から渡された関数を呼び出す
    city = ""; 
  };
</script>

<form on:submit={submitForm}>
  <input type="text" bind:value={city} placeholder="都市名を英語で入力" />
  <button type="submit">Serach City</button>
</form>

・Results
Form コンポーネントから受け取った都市名から検索された
お天気APIの結果を表示します。
※未検索時は、先頭の検索結果(国)が空か否かで表するかを
制御しております。

# 一部抜粋
// Results.svelte

<script>
  export let results;
</script>

<div class="results">
  {#if results.country}
    <div>{results.country}</div>
    <div>{results.cityName}</div>
    <div>{results.temp_c}°C</div>
    <div>
      <img src="https://openweathermap.org/img/wn/{results.icon}@2x.png" alt="Weather icon" />
      <span>{results.description}</span>
    </div>
  {/if}
</div>
・
・
・

・Loading
検索待ち時間やエラーにローディング画面を出力します。
このコンポート自体は、HTML内のdivのclassへ紐付けだけしております。
※CSSにて出力されるようにloadingの項目に追加します。

# 一部抜粋
// Loading.svelte
・
・
・
 <div class="loading"></div>
・
・
・

6.メインコンポートの作成

メインのApp.svelteにお天気APIの検索する関数と
サブコンポーネントを定義します。

scriptタグに以下を定義します。

  // リアクティブ変数
  let loading = false;

  let results = {
    country: '',
    cityName: '',
    temp_c: null,
    description: '',
    icon: ''
  };

  // 天気を取得する関数
  const getWeather = (city) => {
    //const city = event.detail; // イベントデータを取得
    console.log('Received city:', city);
    loading = true; // ローディングを開始

    // APIリクエスト(1111には実際のAPIーKEYを入力ください)
    axios
      .get(`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=1111&lang=ja&units=metric`)
      .then((res) => 
      {  
        //APIから取得したデータを代入
        results = {
          country: res.data.sys.country,
          cityName: res.data.name,
          temp_c: res.data.main.temp,
          description: res.data.weather[0].description,
          icon: res.data.weather[0].icon,
        };
        console.log(results);
        loading = false; // ローディングを終了
      })
      .catch((err) => {
        alert('エラーが発生しました。ページをリロードして、もう一度トライしてください');
        loading = false;
        location.reload();
      });
    };

main タグへ以下を追加し、サブコンポートを定義呼び出します。
使用時にscriptタグへのimportも合わせて実施してください。
(例 import Results from "./lib/Results.svelte";)

<main>
  <div class="wrapper">
    <div class="container">
      <Title />
      <Form onSubmitForm={getWeather} />
      {#if !loading}
        <Results results={results} />
      {:else}
        <Loading />
      {/if}
    </div>
  </div>
</main>

7.動作確認

ブラウザーよりアクセスして天気が表示されるか確認します。

ローマ字で「稚内」を検索してます。
右下は、ディバック用のconsole.logの表示です。

Yahoo天気でも確認します。
概ねあっております。

8.まとめ

今回は、簡単にAPIを用いてアプリを作成してみました。
ReactやVueとは違い戸惑う所もありましたが、
なんとか作成出来ました。

では


いいなと思ったら応援しよう!