ふるてつのぶろぐ

福岡在住のエンジニアです。

写真提供:福岡市

Angular7 で Web アプリを作ろう - Bootstrap 4 を Angular Material に変える

今日すること

こんにちは、ふるてつです。
GW前半。
今回のテーマはAngular Materialです。
最近まわりの人がAngular Materialを使っているのをうらやましく思い、わたしもBootstrapを乗せ換えて使ってみることにしました。
とにかく動きがきれいで魅力的に思えましたし、ソースもわりとシンプルでした。

Bootstrap のアンインストール

そこでまずは Bootstrap関連のパッケージをアンインストールします。
jQueryもBootstrapが依存していたのですが不要になりました。

npm uninstall --save @ng-bootstrap/ng-bootstrap
npm uninstall --save bootstrap
npm uninstall --save jquery popper.js
Angular Materialのインストール

次にAngular Materialをインストールします。
下記リファレンスを参考にします。
https://material.angular.io/guide/getting-started

Step 1: Install Angular Material, Angular CDK and Angular Animations

まずnpmコマンドでMaterialをインストール。

npm install --save @angular/material @angular/cdk @angular/animations
Step 2: Configure animations

リファレンスとは若干違いますが、MaterialModuleを別途新しく追加します。

ng generate module ./utils/Material

使用する可能性があるモジュールをMaterialModuleに全部追加しました。
中身は下記を参照してください。

MaterialModuleソースコード

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { MatGridListModule } from '@angular/material/grid-list';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatCardModule } from '@angular/material/card';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatDividerModule } from '@angular/material/divider';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatTableModule } from '@angular/material/table';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    MatGridListModule,
    MatInputModule,
    MatFormFieldModule,
    MatCardModule,
    MatButtonToggleModule,
    MatDividerModule,
    MatIconModule,
    MatButtonModule,
    MatTableModule,
    MatProgressSpinnerModule,
  ],
  exports: [
    MatGridListModule,
    MatInputModule,
    MatFormFieldModule,
    MatCardModule,
    MatButtonToggleModule,
    MatDividerModule,
    MatIconModule,
    MatButtonModule,
    MatTableModule,
    MatProgressSpinnerModule
  ]
})
export class MaterialModule { }

Step 3: Import the component modules

こちらもリファレンスとは若干異なります。
上記で追加したMaterialModuleapp.module.tsにインポートします。
下記のインポート文を追加しMaterialModule@NgModuleに取り込みます。

import { MaterialModule } from 'src/app/utils/material/material.module';

@NgModule({
  ...
  imports: MaterialModule,
  ...
})
Step 4: Include a theme

styles.cssMaterialビルトインのcssをインポートしておきます。
数種類ありますので好きなものを選ぶと良いでしょう。

@import "~@angular/material/prebuilt-themes/indigo-pink.css";
Step 5: Gesture Support

mat-slide-togglemat-slidermatTooltiphammerjsに依存しているそうなので、インストールしておきます。
頻繁に使う気はしないのですがこの際入れておきます。

npm install --save hammerjs
Step 6 (Optional): Add Material Icons

今回はこちらは実施していません。
Material アイコンを今後使用するようであればその時に改めて行います。

くずれた体裁の整形

いったんAngularを起動すると、案の定、体裁がおかしくなっています。
変更前)
f:id:tetsufuru:20190429021516p:plain:w500
変更後)
f:id:tetsufuru:20190429021552p:plain:w500

今日は取り急ぎサインイン画面を修正します。

CSS Grid の設定

MaterialにはBootstrapのように細かく指定可能なグリッドシステムはない模様です。
Angular Flex-Layoutを使うと良さそうですが、今回まずはCSS Gridを使用します。
わたしの使い方だとこちらで十分そうでなので、作り方はこちらを参考にしました。
qiita.com

サインイン画面は主に4つのパーツに分けています。
それぞれを<div>タグでくくり、下記のようにidを振っています。

  1. signInContent(これは全体)
  2. welcome(ようこそ部分)
  3. signIn(サインイン部分)
  4. forgotPassword(パスワード忘れ部分)
  5. informations(お知らせ部分)

サインイン画面(sign-in.component.html)の概要はこちら

<div id="signInContent">
  <div id="welcome">
    // ようこそ部分
    <h1>ようこそ</h1>
    <h1>Sanrokumaruシステムへ</h1>
    以下略…
  </div>
  <div id="signIn">
    // サインイン部分
    以下略…
  </div>
  <div id="forgotPassword">
    // パスワード忘れ部分
    以下略…
  </div>
  <div id="informations">
    // お知らせ部分
    以下略…
  </div>
</div>

PC画面の場合は、画面左半分にwelcomeを配置します。
あと残りはすべて右側にsignInforgotPasswordinformationsの順に上から並べます。
その定義は全体ではなくコンポーネント固有のsign-in.component.cssに書き入れました。


sign-in.component.cssの内容はこちら

#signInContent {
  display: grid;
  margin: 0;
  min-height: 100vh;
  grid-template-rows: M70 1fr;
  grid-template-columns: 50% 40% 1fr;
  grid-template-areas:
    /* ↓画面左側はすべてwelcome、右側半分はsignIn、forgotPassword、informationsの順に並べる */
    "welcome signIn"
    "welcome forgotPassword"
    "welcome informations";
}

#welcome {
  grid-area: welcome;
  margin-right: 7rem;
  padding-left: 3rem;
  color: whitesmoke;
  background-color: #66BB6A;
  line-height: 7rem;
  height: 100vh;
}

#signIn {
  grid-area: signIn;
  margin-top: 5rem;
}

#forgotPassword {
  grid-area: forgotPassword;
  margin-top: 1rem;
  text-align: center;
}

#informations {
  grid-area: informations;
}

Media Query の設定

あとはレスポンシブ対応ですが、こちらはMedia Queryを使用しました。 設定方法は下記を参考にしました。 sole-color-blog.com

sign-in.component.cssに追記したMedia Queryの内容はこちら

@media screen and (max-width: 640px) {

  /*ここにスマホ用スタイルを記述*/
  h1 {
    font-size: 1.5rem;
  }

  h2 {
    font-size: 1.2rem;
  }

  h3 {
    font-size: 1rem;
  }

  #signInContent {
    grid-template-rows: M100;
    grid-template-columns: 100%;
    grid-template-areas:
      /* ↓welcome、signIn、forgotPassword、informationsの順に縦に並べる */
      "welcome"
      "signIn"
      "forgotPassword"
      "informations";
  }

  #welcome {
    margin-right: 0;
    padding-left: 1rem;
    font-size: 0.5rem;
    line-height: 1.5rem;
    height: 10rem;
    text-align: center;
  }

修正後の画面は下記のようになりました。
色合いもマテリアルチックなものに変えたので、若干雰囲気が変わりました。
以前より良い感じになったと思います。
f:id:tetsufuru:20190429112054p:plain:w500

携帯サイズの時は下記になります。
f:id:tetsufuru:20190429112747p:plain:w100

今日の感想

今日はBootstrapAngular Materialに乗せ換えました。
Bootstrapが良くないという訳ではなかったのですが、わたしのまわりに使っている者がおらず、なかなか進まなかったところでしたので、GWを期に変更しました。
Angular Materialを使っている人は多いので、詰まったらすぐ聞けるのがいいですね。
Media Queryについては、はじめて使いましたが、簡単にレスポンシブ対応ができました。
わたしはBootstrapなしではできないものと勘違いしていましたので、良い勉強になりました。

今回、携帯の画像サイズをいくつまでにすべきか迷ったのですが、取り急ぎmax-width: 640px以下を携帯と判定しました。
それについては正解がいまひとつ分からないので、別途調べようと思います。

では、今日もお疲れ様でした。