中安拓也のブログ

プログラミングについて書くブログ

【Vue.js】Nuxt.jsのひな形を作成する

Nuxt.jsに入門したいので、ひな形の作成からはじめました。

バージョン情報

  • npm 5.6.0
  • yarn 1.5.1

手順

ターミナルを開いて、下記のコマンド実行する。

$ npm i -g @vue/cli @vue/cli-init

Vue CLIが正しくインストールされていることを確認する。

$ vue -V
3.0.3

vue initコマンドでVue.jsのひな形を作成する。
vue initコマンド後に色々と聞かれるが、特にこだわりがなければ全部EnterでOK。

$ vue init nuxt-community/starter-template <project-name>

上記のコマンドでは、nuxt-community/starter-templateというスターターテンプレートを使用して、Vue.jsのプロジェクトを作成している。

$ cd <project-name>
$ yarn # npm iでも可、パッケージのインストールを行なっている
$ yarn dev # npm run dev でも可

上記のコマンド実行後に、ブラウザでhttp://localhost:3000を開くと下記のNuxt.jsのデフォルト画面が表示される。

f:id:l08084:20181021171754p:plain
Nuxt.jsのデフォルトの画面

参考サイト

インストール - NuxtJS

【JavaScript】return なしでもPromiseはメソッドチェーンできる

はじめに

then関数に新しいPromiseオブジェクトを返す機能があるので、then内でPromiseをreturnする処理を書かなくても、Promiseはメソッドチェーンが可能だということを最近知ったのでメモ。

Promiseチェーンの色々な例

はじめにで述べたことを理解するために、色々なタイプのPromiseをメソッドチェーンで繋ぎます

returnなし

then()内でreturnしない場合でも、thenが新しいPromiseを返してくれるのでメソッドチェーンが可能です

// new Promise(resolve => resolve()) と同じ
const promise = Promise.resolve();

// 実行結果
//    A
//    B
//    C
promise.then(console.log('A'))
       .then(console.log('B'))
       .then(console.log('C'));

returnあり

チェーンの次の処理に前の処理の結果を渡したい場合は、then()内に渡したい値をreturnする処理を書く必要があります。
returnした値はthenの機能でPromiseオブジェクトに変換されるので、数値や文字列だけでなく、オブジェクトでもPromiseでもどの値を返しても、Promiseはメソッドチェーンが可能です

数値を伝搬するPromiseチェーン

数値をreturnで次の処理に渡しています。returnした数値はthenの機能でPromiseオブジェクトに変換して渡されます

// new Promise(resolve => resolve()) と同じ
const promise = Promise.resolve();

// 実行結果
// 6
// arrow functionを使っているのでreturnは省略されているが、
// 実際には数値がreturnされている
promise.then(() => 1)
       .then(value => value + 2)
       .then(value => value + 3)
       .then(value => console.log(value));
Promiseを伝搬するPromiseチェーン

PromiseをPromiseチェーンを使って次の処理に渡すこともできます。
次の例では、戻り値がPromiseのサードパーティ製ライブラリのメソッドをreturnしています。

// 戻り値がPromiseのメソッド
this.keychainTouchId.isAvailable()
    .then((res: any) => {
        // 戻り値がPromiseのメソッド
        return this.keychainTouchId.has(BioAuthService.KEY_A);
    }).then((res: any) => {
        // 戻り値がPromiseのメソッド
        return this.keychainTouchId
            .verify(BioAuthService.KEYCHAIN_KEY, `ロックを解除してください`);
    }).then((res: any) => {
        this.password = res;
        // 戻り値がPromiseのメソッド
        return this.storage.get(BioAuthService.KEY_B);
    }).then((res: any) => {
        this.userId = res;
        const params = {
            loginId: this.userId,
            password: this.password,
            deviceToken: null
        };
        this.action.login(params);
    }).catch((error: any) => {
        // catchは一つでよい
        console.error(error);
    });

結論

何も考えずにthenでつないどけば、Promiseはメソッドチェーンが可能

参考サイト

JavaScript Promiseの本

Promiseを使う - JavaScript | MDN

HTMLメールのCSSなどレイアウト設定について

はじめに

最近仕事でHTMLメールのレイアウトを設定する機会があったので、HTMLメールを作成するときの注意点や参考サイトなどをまとめました

ベースになるテンプレート

HTMLメールを作るのが初めての人は、そもそもHTMLメールのHTMLってどう書けばいいの?ってなると思うんですが、それについてはGmailの公式サイトの方で説明してくれています。

CSS Support  |  Gmail Sender Resources  |  Google Developers

  • Gmail公式が紹介しているHTMLメールのテンプレート
<html>
  <head>
    <style>
      .colored {
        color: blue;
      }
      #body {
        font-size: 14px;
      }
    </style>
  </head>
  <body>
    <div id='body'>
      <p>Hi Pierce,</p>
      <p class='colored'>This text is blue.</p>
      <p>Jerry</p>
    </div>
  </body>
</html>

Gmailについては上記のテンプレートでいいですが、メールクライアントによっては、インラインCSSでないとダメなクライアントもあると思います(調べてませんが)。
そのようなメールクライアントへの対応が必要な場合は、下記のようなCSSをインラインCSSに変換するサービスを使うと便利です。

CSSをインラインCSSに変換してくれるWebサービス「Inline styler」 | ネットショップ運営の気になる備忘録

メールクライアントごとの違い

メールクライアント(Gmail, Outlook, Yahoo!メール...)ごとに、使用できるCSSやHTMLタグが大きく異なるため特に注意が必要です。

HTMLメールのレイアウトを検証できるサービス

メールアドレスとHTMLメールのテンプレートを入力するとメールを送信してくれるサービスもあります。メールを送信する環境を構築しなくてもレイアウトの確認ができるので便利

New Email Test — Litmus PutsMail

【HTML】押すと電話がかかるボタンを作る

はじめに

押すと、電話がかかるボタンを作りたい

TELリンクを使う

a要素href="tel:[電話番号]"を設定すると、電話発信用のリンクを作ることができる。

<a href="tel:090XXXXXXXX">電話をかける(090XXXXXXXX)</a>

f:id:l08084:20180901153652p:plain
実際の表示

TELリンクをボタン風に表示する

TELリンクを設定したa要素(アンカータグ)でボタンを囲むことによって、クリックすると、電話を発信するボタンが完成する

<a href="tel:090XXXXXXXX">
  <button ion-button>電話をかける(090XXXXXXXX)</button>
</a>

f:id:l08084:20180901154743p:plain
実際の表示

PCでこのボタンを押すと、FaceTimeだったりSkypeだったりを呼び出してくれる

f:id:l08084:20180901154901p:plain

参考サイト

HTML5/テキスト/a要素 電話発信用のリンクを設定する - TAG index

【Java8】年月日の計算が簡単にできる Date and Time APIについて

新卒ぶりくらいにJavaを触ったら、日時の計算が楽にできるようになってて驚いた

この記事について

Java8で導入された Date and Time API による、日時の計算についてのメモ

Date and Time API

Date and Time APIでは、Java8以前の日付クラス(java.util.Date, java.util.Calender)と比べて、下記の特徴・メリットがあります。

  • 日付・時間・日時をそれぞれ別クラスで扱っている(不要な情報を持たなくてよい)
  • 年月日の計算が楽

日付・時間・日時をそれぞれ別クラスで扱う

Date and Time APIでは、日付・時間・日時を扱うクラスが次のように3つに別れています。

  • 日付
    • java.time.LocalDate クラス
  • 時間
    • java.time.LocalTime クラス
  • 日時
    • java.time.LocalDateTime クラス

コード

実際にDate and Time APIを使って、日時処理をしていく

現在の日付、時間、日時の取得

// 日付
LocalDate date = LocalDate.now();
// 出力: 2018-08-26
System.out.println(date);

// 時間
LocalTime time = LocalTime.now();
// 出力: 14:06:44.359369
System.out.println(time);

// 日時
LocalDateTime dateTime = LocalDateTime.now();
// 出力: 2018-08-26T14:06:44.359400
System.out.println(dateTime);

実行結果

2018-08-26
14:06:44.359369
2018-08-26T14:06:44.359400

StringからLocalDateに変換

文字列をLocalDate型に変換する

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class TestDate {
    public static void main(String... args) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        String text = "2017/03/08";

        // StringからLocalDateに変換
        LocalDate localDate = LocalDate.parse(text, formatter);

        // 出力: 2017-03-08
        System.out.println(localDate);
    }
}

実行結果

2017-03-08

LocalDateからStringに変換

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class TestDate {
    public static void main(String... args) {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

        // 現在の日付を取得
        LocalDate localDate = LocalDate.now();

        // StringからLocalDateに変換
        String formattedString = localDate.format(formatter);
        // 出力: 2018年08月26日
        System.out.println(formattedString);
    }
}

実行結果

2018年08月26日

生年月日から年齢を計算する

生年月日から、その人の年齢を計算する

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class TestDate {
    public static void main(String... args) {

        // 生年月日
        String birthdate = "1989/10/16";

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        // 生年月日を表す文字列から、LocalDateを生成
        LocalDate localBirdhdate = LocalDate.parse(birthdate, formatter);

        // 現在の日付を取得
        LocalDate nowDate = LocalDate.now();

        // 現在と生年月日の差分を年単位で算出することによって、年齢を計算する
        long age = ChronoUnit.YEARS.between(localBirdhdate, nowDate);

        // 年齢: 28
        System.out.println("年齢: " + age);
    }
}

実行結果

年齢: 28

年月日の計算

日単位の加算を行ったり、差分を日・時間・分 単位で出したりなど

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class TestDate {
    public static void main(String... args) {

        // 現在の日時を取得
        LocalDateTime nowLocalDate = LocalDateTime.now();

        // 現在の日時の1日後を取得
        LocalDateTime nextLocalDate = nowLocalDate.plusDays(1);

        // 今日と明日の差分を日単位で取得
        long days = ChronoUnit.DAYS.between(nowLocalDate, nextLocalDate);

        // 今日と明日の差分を時間単位で取得
        long hours = ChronoUnit.HOURS.between(nowLocalDate, nextLocalDate);

        // 今日と明日の差分を分単位で取得
        long minutes = ChronoUnit.MINUTES.between(nowLocalDate, nextLocalDate);
        
        System.out.println("現在の日付: " + nowLocalDate);
        System.out.println("明日の日付: " + nextLocalDate);
        System.out.println("差分(日): " + days);
        System.out.println("差分(時間): " + hours);
        System.out.println("差分(分): " + minutes);

    }
}

実行結果

現在の日付: 2018-08-26T17:37:26.337370
明日の日付: 2018-08-27T17:37:26.337370
差分(日): 1
差分(時間): 24
差分(分): 1440

参考サイト

Javaで2つの期間より差を検出する。 - m_shige1979のささやかな抵抗と欲望の日々

【CSS】PCでもモバイルと同じレイアウトの画面で表示する(スマホのフレーム画像に画面をはめる)

今回やること

PCからみると、スマホの枠の中にコンテンツが表示されるようなデザインの画面を作る。参考サイト(フィッシャーマン・コール)

f:id:l08084:20180819164939p:plain
PCだとこーいう表示になる

f:id:l08084:20180819165154p:plain
モバイルからだとこういう表示になる

メリット

PC用の画面デザインを用意せずに、スマホ用のレイアウト一本でいける

大まかな流れ

  1. 表示している端末がPCかモバイルかを判定する
  2. (PCの場合)スマホのフレーム画像を表示する
  3. (PCの場合)画面をスマホの枠に当てはまるように、指定の高さ、幅で表示する
  4. (モバイルの場合)スマホのフレーム画像を表示しない
  5. (モバイルの場合)画面をスクリーンいっぱいに表示する

コード

HTMLとCSSを書いていく

メディアクエリを使用する

メディアクエリを使って、画面の幅でPCかモバイルかを判定する

  @media screen and (max-width: 760px) {
     /* 760pxの幅まで適用される(モバイルの時のレイアウト) */
    .frame {
      /* モバイルの時は、スマートフォンのフレーム画像を表示しない */  
      display: none;
    }
  }

  @media screen and (min-width: 760px) {
     /* 幅が760pxより大きい時に適用される(PC用のレイアウト) */
    .frame {
      /* スマホのフレーム画像を上下中央に表示 */
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      margin: auto;
      z-index: 5;
      width: 450px;
      height: 787px;
      .frame-img {
        position: relative;
        margin-top: 20px;
        margin-left: -1.3px;
      }
      /* コンテンツをスマホのフレーム内に収まるように上下中央に表示 */
      .main {
        width: 376px;
        height: 603px;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
        z-index: 10;
      }
    }

HTMLはだいたいこんな感じで

<div class="frame">
  <!-- スマホのフレーム画像 -->
  <img alt="" src="./assets/imgs/phone-frame.png" class="frame-img">
</div>
<!-- 表示するコンテンツ -->
<ion-nav class="main" [root]="rootPage"></ion-nav>

【JavaScript】reduceを使ってオブジェクトの配列から一番大きいIDを取得する

モチベーション

強力そうだけどいまいち使いこなせていない関数筆頭のArray.prototype.reduce()について、ちゃんと習得したいという思い

バージョン情報

  • Angular: 6.0.3
  • Typescript: 2.7.2

今回やること

下記のオブジェクトの配列から、reduce()を使って値が最大のIDを取得してみる

  weapons = [
    {id: 1, name: 'ブロードソード', power: 117},
    {id: 2, name: '太陽の直剣', power: 112},
    {id: 3, name: '輪の騎士の直剣', power: 120}
  ];

コードとしては、下記のように書けば最大のIDを取得することができる

// リスト内で一番大きいIDを取得
const max = this.weapons.reduce((a, b) => a > b.id ? a : b.id, 0);

(a, b) => a > b.id ? a : b.idは、reduceのコールバック関数、0はreduceの最初の引数になるinitialValueとなる。
コールバック関数の引数aはコールバックの戻り値を累積するaccumulator(ひとつ前の処理結果または initialValue を指す)にあたり、bは現在処理されている配列要素であるcurrentValueとなる。
処理内容としては、「0と最初の配列要素のidと比較して、大きい方を次の配列要素のidと比較して、大きかった方をさらにその次の配列要素のidと比較して...」という流れになる。

上記のサンプルコードを使用して、配列にオブジェクトを追加するコードを書いてみる

app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
            名前<input type="text" (keyup)="name=$event.target.value">
          <button (click)="addWeapon()">武器を追加</button>
          <ul>
            <li *ngFor="let weapon of weapons">
              ID:{{ weapon.id }} {{ weapon.name }} 攻撃力:{{ weapon.power}}
            </li>
          </ul>
`
})
export class AppComponent {
  name: string;
  weapons = [
    {id: 1, name: 'ブロードソード', power: 117},
    {id: 2, name: '太陽の直剣', power: 112},
    {id: 3, name: '輪の騎士の直剣', power: 120}
  ];

  // 新しい武器を追加する
  public addWeapon(): void {
    // リスト内で一番大きいIDを取得
    const max = this.weapons.reduce((a, b) => a > b.id ? a : b.id, 0);
    // 新しい武器をリストに追加
    this.weapons.push({
      id: max + 1,
      name: this.name,
      power: 200
    });
  }
}

動作確認

サンプルコードを実際に動かしてみる

テキストフォームに、武器名を入力して... f:id:l08084:20180819160226p:plain

「武器を追加」ボタンを押すと、最大のIDが採番された状態でリストに武器が追加されていることがわかる f:id:l08084:20180819160244p:plain

参考サイト

Array.prototype.reduce() - JavaScript | MDN