17
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Angularでの基本的なページレイアウトを理解する

Last updated at Posted at 2019-06-16

前回ではAngularのプロジェクトを構成する、”コンポーネント”、”モジュール”につて解説していきました。
Angularプロジェクトの構成

今回はそれらを使って基本的なページのレイアウトを組んでいきたいと思います!

それではいきましょうーー!

Headerの実装

前回作ったheaderコンポーネント(鬼誤字ってました恥ずかしい。。。)を以下のように修正して実際にヘッダーを作っていきましょう!
スクリーンショット 2019-06-09 23.30.05.png

少しみづらいかもしれませんが、上から
src/app/header/header.component.ts
src/app/app.component.html
src/app/header/header.component.html

になります!

スクリーンショット 2019-06-09 23.32.58.png こんな感じで表示されるはずです!

それではヘッダーを作っていきましょう!
自分で作ってもいいですし、コピペしてくれても構いません!

header.component.html
<header>
  <div class="header-content">
    <div class="logo">
      <a>ロゴだよー</a>
    </div>
    <nav class="navbar">
      <ul>
        <a href=""><li>menu1</li></a>
        <a href=""><li>menu2</li></a>
        <a href=""><li>menu3</li></a>
      </ul>
    </nav>
  </div>
</header>
header.component.scss
header {
  width:                   100%;
  height:                  50px;
  background-color:        #2f3033; 

  .header-content {
    width:                 960px;
    height:                100%;
    margin:                auto;
    position:              relative;

    .logo {
      position:            absolute;
      top:                 50%;
      left:                0;
      transform:           translate(0,-50%);
      font-weight:         bold;
      color:               white;
      font-size:           20px;
    }

    nav {
      position:            absolute;
      top:                 50%;
      right:               0;
      transform:           translate(0%,-50%);

      ul {
        list-style:        none;
        margin:            0;

        li {
          display:         inline-block;
          color:           white;
          padding:         10px;
        }

        li:hover {
          background-color: grey;
          color:            black;
        }
        
        a {
          margin-left:      30px;
        }
      }
    }
  }
}

強引感強くてすいません。。。笑
でもこれでこんな感じのヘッダーができたはず!
タイトルなし.gif

Footerの実装

お次はフッター!
以前ヘッダーを作ったように、フッターも作っていきましょう!

$ ng g c footer   // ← g(generate),c(component)と略せる
CREATE src/app/footer/footer.component.scss (0 bytes)
CREATE src/app/footer/footer.component.html (25 bytes)
CREATE src/app/footer/footer.component.spec.ts (628 bytes)
CREATE src/app/footer/footer.component.ts (270 bytes)
UPDATE src/app/app.module.ts (557 bytes)

適当に、、、、、

<footer>
  <div class="footer-content">
    <ul>
      <a href=""><li>footer rink1</li></a>
      <a href=""><li>footer rink2</li></a>
      <a href=""><li>footer rink3</li></a>
      <a href=""><li>footer rink4</li></a>
    </ul>
  </div>
</footer>

a {text-decoration: none;}

footer {
  width:                  100%;
  height:                 170px;
  margin-top:             30px;
  background-color:       #2f3033;
  position:               relative;
  
  .footer-content {
    display:              flex;
    width:                200px;
    height:               100%;
    margin:               auto;

    ul {
      list-style:         none;
      color:              white;

      li {
        padding:          5px;
        color:            white;
        list-style:       none;
      }
   
      li:hover {
        background-color: grey;
        color:            black;
      }
    }
  }
}

headerを追加した時のようにapp.cmponent.htmlにfooterを追加すれば表示されます


<app-header></app-header>

<router-outlet></router-outlet>

<app-footer></app-footer>

とりあえずヘッダーとフッターぽいのができましたね!
スクリーンショット 2019-06-16 19.07.47.png
いや前から気になってたけど<router-outlet>って誰?
ってなる人もいると思います
でもその前に各viewがどのように表示されていくのか、全体の構造を一旦整理した方がいいので一旦プロジェクトのsrc/index.htmlを見てみましょう、こいつが一番親のviewにあたります

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>ExampleAngular</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

すごくシンプルなHTMLなんですが、<app-root>のタグがありますね
今までの作業から、こいつがapp-rootを定義しているコンポーネントの中を参照していることがわかります

一個下の階層にあるapp.component.tsがそれを定義していて、app-rootのviewに当たるapp.component.htmlには先ほど追記したapp-headerapp-footer、得体の知れないrouter-outletがいると思います。

こんな風に大枠のコンポーネントの中に細々としたコンポーネントを作って一つのページができていることがわかりますね!

#####うんそれはわかったけどめっちゃでかい1つのページ作る気?このままだと作りたいものすべてが一個のページに詰まっちまいそうだよ

はい。プログラミング未経験の僕もそう思ってました。
スクリーンショット 2019-06-16 20.25.27.png
こんな風に各URLに各HTMLがいるもんだと思っていましたが今回は全体では一個だけ。
初めはピンときませんでした。。。

##SPA?

でも色々調べると、どうやらSPAとかいうものの概念を理解しないとダメらしいので調べてみた。
SPA(Single Page Application)ってなに?

一部抜粋

SPAとは単一のWebページでアプリケーションを構成する設計構造の名称です。

単一のWebページでコンテンツ切り替えを行うことで、ページ遷移の必要がなく、ブラウザの挙動に縛られないWeb表現を可能にするのです。

むむ、単一のWebページ?なんかすごそう
一応デメリットもありまして

初期ローディングに時間がかかる
実装コストが大幅に増える

らしい。

AngularもSPAを作るためのフレームワークらしく、ページ自体は単一で、中のコンテンツ(コンポーネント)を切り替えることで、ページ転移を擬似的に行うことができる。すごい。("普通SPAの理解が先だろ"とは言わないでください。わかっております)

はい。これでSPAとページ全体の構造が理解できましたね〜!

で、おおもとに帰ります。

↑らのことから空気を読むとrouter-outletが表示を切り替えてくれる役割なんだなーってのが予想できます

routingについて

さっきも言いましたが、SPAでのroutingはページの転移ではなく、表示されているコンテンツ(コンポーネント)の切り替えなので、サーバーを経由しません。(要するに画面転移時にロード画面にならずにすぐ表示される(厳密にいうと違う)。その分初めにロードするから初期ロードが長いよねーって話)

実際にどうやって設定していくかといいますと、実はこの記事を読みながらangular cliでプロジェクトを作った人はすでに設定が終わっています。

Angularプロジェクトの作成
スクリーンショット 2019-06-16 21.53.59.png
この上から3行目のところをyesにするとsrc/app/app-routing.module.tsが作られて、src/app/app.module.tsのimportの部分にAppRoutingModuleが自動で追加されます
作ってない人は以下のコマンドで作ってください

$ng generate module app-routing --flat --module=app

じゃぁ新しいコンポーネントを複数作ってroutingも実装してみましょう!

$ ng g c top                // トップページ
.....
...
..
$ ng g c sign-in            // ログインページ
....
...
..
$ ng g c sign-up            // 会員登録ページ
....
...
..

top,sign-in,sign-upの3つのコンポーネントを作ってみましょう!(あとで使います)
angular/cliを使ってcomponentをgenerateするときはsrc/app以上の階層でやるとapp/配下に作られるようになっていて、階層を指定したければ、そのディレクトリ直下で作成すれば大丈夫です!

各コンポーネントのhtmlにはデフォルトで

<p>
  (file名) works!
</p>

のように作られるので今は特に編集しなくても切り替わった時に違いがわかるでしょう.

実際にroutingのファイルに設定を追記していきます

src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import {SignUpComponent} from 'src/app/sign-up/sign-up.component';
import {TopComponent} from 'src/app/top/top.component';
import {SignInComponent} from 'src/app/sign-in/sign-in.component';

const routes: Routes = [
    { path: 'top',        component: TopComponent    },
    { path: 'signup',     component: SignUpComponent },
    { path: 'signin',     component: SignInComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

内容はわかりやすいですね!
/topにアクセスしたらTopComponent。他も同様です

実際にアクセスしてみましょう!
http://localhost:4200/top
トップページ
スクリーンショット 2019-06-16 22.23.57.png

http://localhost:4200/signup
会員登録ページ
スクリーンショット 2019-06-16 22.24.10.png

http://localhost:4200/signin
ログインページ
スクリーンショット 2019-06-16 22.24.21.png

####wa---i !!

もうわかっているとは思いますが、ヘッダーや、フッターのような全ページに共通するパーツはapp.component.htmlに直接書いておけばこんな風にずっとくっついてきます。
図で書くと⬇︎みたいな感じですね!
スクリーンショット 2019-06-16 19.54.05.png

これでテンプレート(html)とスタイル(css)を各コンポーネントに実装してrouting実装するだけで簡単なホームページくらいは作れそうですね!

次回はangular独自のhtmlタグについて書いていきます!

今回の記事に関連したリンク
https://qiita.com/daikiojm/items/46f6b2b355f9f73536e1
https://www.isoroot.jp/blog/1285/
https://digitalidentity.co.jp/blog/creative/about-single-page-application.html

17
18
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?