Angular 「スマホ・PC」でcomponentとCSSを切り替える(分岐させる)方法
2017.10.15
この記事は最終更新日から1年以上が経過しています。
どもです。
今回は、AngularやVueJSを使って、webサイトやwebサービスを作成していると「PC・スマートフォン」の表示も作って行かないといけなくて、「レスポンスシブ」に組んで行くのもちょっと無理がある。
って時は「component」と「CSS」を切り替えたくなってくるかと思います。
今回は、その「component」と「CSS」をそれぞれ、「PC用とスマートフォン用」にフレームワーク側で分岐してくれるように作っていきたいと思います。
方法に関してもググってみても余り出てこなかったので、せっかくなので書いておきます。
今回のを図で表すと、このような感じです。
Angularのcomponentに、cssファイルパスを指定して読み込んだStyleは、component単位で適応範囲を絞られますが、「PC、SP」それぞれ全体に適応するようにも設定していきます。
今回のフレームワークは「Angular」(v.4.2.4)を利用してやっていきたいと思います。(VueJSは次回にでも)
すぐに試したい方は、GitHubの方にも一式上げていますので、そちらを参照して頂ければと思います。
GitHub
https://github.com/webcyou/ang-sp-pc-template
ng CLIでテンプレート作成
では、早速作っていきます。
ngCLIを使ってAngularテンプレートを生成します。
インストールがまだの方はこちらの記事等を参考にインストールしましょう。
$ ng new ang-sp-pc-template
ディレクトリ移動
$ cd ang-sp-pc-template
「npm run start」でアプリケーションが立ち上がるのを確認。
$ npm run start
ブラウザで「http://localhost:4200/」で確認できれば成功です。
APB CLIで、SCSSディレクトリ作成
次にSCSSディレクトリを作って行きましょう。
Angularのcomponentに、cssファイルパスを指定して読み込んだStyleは、component単位で適応範囲を絞られますが、「PC、SP」それぞれ全体に適応するようにも設定していきます。
今の流れで「アトミックデザイン」のアーキテクチャを取り入れた「CSSアーキテクチャ」APBCSSの構成で作っていきたいと思いますので、「APB CLI」を用いてテンプレートを生成していきます。
「APB CLI」のインストールがまだの方は、こちらの記事等を参考にインストールしましょう。
まずは、ディレクトリを作成
$ mkdir src/assets/scss
「APB CLI」のapb newでテンプレートを生成。
$ apb new sp
$ apb new pc
これだけで、この様にSCSSファイルが生成出来たかと思います。
node-sassとconcurrentlyのインストール
package.jsonのディレクトリに戻り、SCSSのコンパイルの為「node-sass」パッケージと、npm run scriptを同時に実行するために「concurrently」をインストールします。
$ npm install node-sass --save-dev
$ npm install concurrently --save-dev
package.jsonのrun scriptの追加と修正を行います。
“scripts”: { 内に以下を追加します。
package.json
"sass-pc":"node-sass --include-path scss src/assets/scss/pc/style.scss src/style.pc.css -w", "sass-sp":"node-sass --include-path scss src/assets/scss/sp/style.scss src/style.sp.css -w”
“scripts”: { 内の「start」を修正します。
"start":"concurrent\"ng serve\" \"npm run sass-pc\" \"npm run sass-sp\””,
それでは、コンパイルとngサーバーが起動するか確認しましょう。
$ npm run start
scssのコンパイルが走り、cssファイルが生成されるとng サーバーが立ち上がり、ブラウザで「http://localhost:4200/」で確認できれば成功です。
PC SPのcomponentを作成
続いて、「component」の作成を行っていきます。
componentディレクトリを作成し、「pc」「sp」それぞれのディレクトリを用意します。
$ mkdir src/app/component/pc/ $ mkdir src/app/component/sp/
pc、spそれぞれ「app.xx.component.html」「app.xx.component.html」「app.xx.module.ts」「index.ts」を用意。
ページを想定した「top」ディレクトリとcomponentも用意。
準備が完了しましたら、それぞれ記述していきます。
まずは、「app.pc.component.ts」。
こちらは、pc側のcomponentのルートとなるファイルになります。
cssファイルをPC、SPそれぞれに適したパスの記述する以外は、以下の様に特に変わった記述は行いません。
app.pc.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-pc-root', templateUrl: './app.pc.component.html', styleUrls: ['../../../style.pc.css'] }) export class AppPcComponent { }
次に「top.component.ts」を作成。
こちらは、ページ等、実際に利用するcomponentを想定に作成しております。
app-top セレクタで呼び出せるように記述。
top.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-top', templateUrl: './top.component.html' }) export class TopComponent { }
app.pc.component.htmlには、先程作成した「top.component.ts」 を読み込みます。
app.pc.component.html
<app-top></app-top>
これらのcomponentをまとめる「app.pc.module.ts」を作成します。
declarationsとexportsに、それぞれのcomponentを記述。
app.pc.module.ts
import { NgModule } from '@angular/core'; import { AppPcComponent, TopComponent } from './index'; @NgModule({ declarations: [ AppPcComponent, TopComponent ], exports: [ AppPcComponent, TopComponent ], }) export class AppPCModule { }
index.tsは主に、componentをまとめるファイルですが、省略してapp.pc.module.ts
に記述しても問題ありません。
index.ts
export * from './app.pc.component'; export * from './top/top.component';
ここまでできれば、一通り完成。
PC側を作成したので、SP側も同じ様に記述していきます。
SP側は割愛させていただきます。
ルートの設定
それでは、切り替えを行うルートの設定をしていきます。
ユーザーエージェントを取得するため、「ua-parser-js」等を使用してもよいのですが、
GitHub
https://github.com/faisalman/ua-parser-js
「is.js」の方がシンプルに書けそうだったので、そちらを使用してみます。
「is.js」
GitHub
https://github.com/arasatasaygin/is.js
npmでインストール。
$ npm install is_js --save
インストール出来たら、app.component.tsを修正していきます。
「’is_js’」をimportし、「is.mobile()」で、アクセスしてきたのは、PCかSPを判定します。
app.component.ts
import { Component } from '@angular/core'; import is from 'is_js'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { public isMobile: boolean = is.mobile(); }
アクセスしてきたのは、PCかSPで、呼び出すcomponentを切り替えます。
app.component.html
<app-pc-root *ngIf="!isMobile"></app-pc-root> <app-sp-root *ngIf="isMobile"></app-sp-root>
「app.module.ts」には、それぞれのmoduleである「AppPCModule」と、「AppSPModule」を、importsとexportsに記述すれば完成。
app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppPCModule } from './component/pc/app.pc.module'; import { AppSPModule } from './component/sp/app.sp.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, AppPCModule, AppSPModule ], exports: [ AppPCModule, AppSPModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
と、ここまでで一旦完成!!
ブラウザで「http://localhost:4200/」で確認すると、PCでのアクセスと、SPでのアクセスで表示が切り替わっているのが確認出来るかと思います。
スマートフォン
PC
CSSを調整
最後に、CSSの設定を行います。
Angularのコンポーネントスタイルでは、componentに、cssファイルパスを指定して読み込んだStyleは、component単位で適応範囲を絞られますので、Shadow DOMに由来する特殊なセレクタを使用し、適応範囲を広げます。
PC,SPのstyle.scssそれぞれのファイルに「:host /deep/」を記述して、子コンポーネントに適応させます。
style.scss
:host /deep/ { @import "common_inc"; @import "parts"; @import "pages/pages_inc"; }
:host擬似クラスセレクタは、そのコンポーネント自身にマッチします。(コンポーネント内のすべての要素に適応されるわけではないです)
コンポーネントスタイルは基本的に、自身のテンプレート内にしか適用されないのですが、/deep/セレクタを使うと、強制的に子コンポーネントの内部にスタイルを適用することができます。
/deep/セレクタは「>>>」 に置き換えることができますが、SCSSのコンパイルだと、「> > >」とスペースが入ってしまい適応されなかったので「/deep/セレクタ」を使用しています。
その他にも「:host-contextセレクタ」などもありますが、説明は割愛させて頂きます。
PCだけfont-sizeを変更してみましたら、PCのみ適応されました。
と、言ったわけで簡単でしたが、PC、スマートフォンのアクセスによって「component」「SCSS」を切り替える方法でした。
今回のソースは、GitHubの方にも一式上げていますので、そちらを参照して頂ければと思います。
GitHub
https://github.com/webcyou/ang-sp-pc-template
次回は「VueJS」での方法を書いていきますー
ではぁではぁ。