20200812のvue.jsに関する記事は12件です。

【 Vue.js】無料APIを利用した、世界の為替とビットコイン価格一覧ページの作成方法

【 Vue.js】無料APIを利用した、世界の為替とビットコイン価格一覧ページの作成方法

無料APIを使って、リアルタイムのビットコイン現在価格と為替(対日本円)の一覧を表示するページを作成する方法。

完成図

image.png

<主な機能>
・日本円ビットコイン価格
・現在時刻の表示
・米ドルビットコイン価格
・日本円為替
・国コードとビットコイン価格、為替一覧表

作成手順

  1. 日本円ビットコイン価格の表示
    1. APIによるビットコイン価格の取得
    2. JPY/USD為替の取得
    3. 現在時刻の取得
    4. 四捨五入フィルタの作成
    5. 1000桁区切りフィルタの作成
    6. テーブルの作成とスタイル調整
  2. ビットコイン価格一覧表の表示
    1. 小数点桁数指定フィルタの作成
    2. 元データの確認
    3. v-forによるデータ読み込み
    4. テーブルのスタイル調整
  3. 確認用コード


1. 日本円ビットコイン価格の表示

日本円ビットコイン価格の表示部を作成していく。

image.png


1-1 APIによるビットコイン価格の取得

axios使用準備

まずは無料APIを使ってビットコイン価格を取得する。指定URLにアクセスしてデータを取得するために、axiosというJavaScriptのライブラリを使用する。

axiosを使うためにはプロジェクト内へのインストールなど事前準備が必要。準備方法は下記ご参照。

Vue CLIでaxiosを使う方法
通常のページでaxiosを使う方法


mountedオプションでaxiosを使ってデータを取得する

▼axiosでデータを取得する方法
axios.get('URL').then(function(res){処理}.bind(this))

引数のresは任意。この変数に取得したデータを格納する。

・無料APIはcoindeskの下記エンドポイントを使用。
https://api.coindesk.com/v1/bpi/currentprice.json



取得できるデータは、リアルタイムのビットコイン価格のUSD, EUR、GBP(イギリス£)の3つのみのため、EURとJPYのリアルタイム為替を別途取得する必要がある。

ビットコイン価格取得するプログラムは下記になる。

.js(script)
export default {
  name: 'BitcoinAPI',
  data: function(){
    return{
        //ビットコイン価格格納用
        bpi: null,
    }
  },
  mounted: function(){
    //ビットコイン現在価格取得
    axios.get('https://api.coindesk.com/v1/bpi/currentprice.json')
    .then(function(response){

        //デバッグ用
        console.log(response.data.bpi)
        this.bpi = response.data.bpi
    }.bind(this))

    //通信エラー用
    .catch(function(error){
        console.log(error)
    })
   }
}

※今回のプログラムはVue CLIのプロジェクトで作成しているため、export defaultやdataオプションの中にfunctionが記載されている。(根本的にはVue CLIを使わない場合も同様の考え方で問題ない)

・mountedオプションとは?
処理を実行するタイミングを指定するもので、Vueインスタンスを作成した後に実行される。

Vueライフサイクルハック

this.bpi = response.data.bpiとは?
取得したデータは変数responseに格納される。ビットコイン価格はdataプロパティの中の、bpiプロパティの中に入っている。(ここまではAPI側の設定)

これをdataオプションで定義した変数bpiに格納する。(こちら側の設定)


1-2 JPY/USD為替の取得

上記APIで取得したビットコインの価格はEURのため、EURと日本円の為替を取得する。

APIは下記を使用。
https://api.exchangeratesapi.io/latest

※注意:為替はユーロベース
(登録不要で日本円/USDを取得できるAPIがあれば教えてください)

・日本円/EUR格納用に変数jpyEurを用意。
・日本円/USD格納用に変数jpyUsdを用意。
・ユーロベースのため、JPY/EURをUSD/EURで割ることで、JPY \USD価格を取得する。

.js(script)
export default {
  name: 'BitcoinAPI',
  data: function(){
    return{
        jpyEur: '',
        jpyUsd: ''
    }
  },
  mounted: function(){
   //為替取得
 axios.get('https://api.exchangeratesapi.io/latest')
    .then(function(res){
        //デバッグ用
        console.log(res.data.rates)
        this.jpyEur = res.data.rates.JPY
        this.jpyUsd = res.data.rates.JPY/res.data.rates.USD
    }.bind(this))
    .catch(function(error){
        console.log(error)
    })
   }
}

*可読性向上のため、為替取得に必要なコードのみ記載。

・JPY/EURの為替
res.data.rates.JPY

・USD/EURの為替
res.data.rates.USD

・JPY/EURの為替
res.data.rates.JPY/res.data.rates.USD


1-3 現在時刻の取得

データをロードしたタイミングの時刻を表示する。JavaScriptのnew Date()で現在時刻を生成し、toLocaleStringメソッドでマイクロ秒などの不要な部分をカット。

生成した時刻は変数nowに格納する。

.js(script)
  data: function(){
    return{
        now: '',
    }
  },
  mounted: function(){
    //現在時刻取得
    this.now = new Date().toLocaleString()
   }
}


1-4 四捨五入フィルタの作成

取得したビットコイン価格および、算出した数値は小数点を多く含むため、四捨五入するフィルタを作成する。

フィルタの作成方法

グローバルで使えるフィルタを作成する。フィルタの作成はJSファイルで、Vue.filterを使い、フィルタ名と処理を記述する。

Vue.filter('フィルタ名', function(value){return 処理}}

Vue CLIでフィルタを作成する場合は、filterをモジュールとして作成し、main.jsでインポートする必要がある。

Vue CLIでフィルタを作成する方法
(参考)ローカルフィルタの作成方法

四捨五入フィルタの作成

四捨五入はJavaScriptのMath.roundメソッドを利用する。
Math.round(数値)

小数点の桁数を指定して四捨五入する場合は、その桁数を整数にするだけ10を掛け、四捨五入後に掛けた10の値で割る。

▼小数点2桁目で四捨五入する場合
Math.round(value*100)/100

.js(script)
//小数点0桁目で四捨五入
Vue.filter('MathRound', function(value) {
  return Math.round(value);
})

//小数点1桁目で四捨五入
Vue.filter('MathRound1', function(value) {
  return Math.round(value*10)/10;
})

//小数点3桁目で四捨五入
Vue.filter('MathRound3', function(value) {
  return Math.round(value*1000)/1000;
})


1-5 1000桁区切りフィルタの作成

日本円換算の1ビットコインの価格は100万前後と桁数が多いため、1000桁区切りするフィルタも作成する。

JavaScriptのtoLocaleStringメソッドを使用する。
数値.toLocaleString()

.js(script)
Vue.filter('1000separator', function(value) {
  return value.toLocaleString();
})


1-6 テーブルの作成とスタイル調整

表示するためのデータと下準備が整ったので、表を作成する。

表は2行×2列。縦をth(table head:見出しセル)とする。

<テーブルの基本構造>
tableタグの構造は階層構造をとる。最小構成はtableタグとtdタグ。その他は表の構造や可動性を考慮して設置する。

  • table
    • tbody
    • thead
    • tfoot
      • tr
        • th
        • td

今回は、table > tbody > tr > th, tdタグの4種を使用。CSSスタイル適用のため、適当にclass, id名を振り分ける。

表示するデータ

・データの表示はマスタッシュ展開{{}}を使用。
  ┗ vueテンプレートの中でマスタッシュ展開を使うとデータを呼び出せる(データバインディング)。
・フィルタの適用はマスタッシュ展開の中でパイプ「|」+フィルタ名。

  • bpi.EUR.rate_float * jpyEur : 日本円ビットコイン価格
  • | MathRound:四捨五入フィルタの適用
  • | 1000separator:1000桁区切りフィルタの適用
  • bpi.USD.rate_float:ビットコインUSD価格(小数点表示)
  • now : 現在時刻の呼び出し
.html(template)
      <h1>Bitcoin API</h1>
      <div id="wrapper">
        <div id="content-wrapper">
          <h2 class="table-title">ー 現在のビットコイン価格 ー</h2> 
          <table id="main-table"> 
            <tbody> 
              <tr id="first-tr"> 
                <th>現在値</th> 
                <td id="first-td"> 
                  <em>¥{{bpi.EUR.rate_float * jpyEur | MathRound | 1000separator}}</em> <span class="small-letter">({{now}})</span> 
                </td>
              </tr> 
              <tr>
                <th>米ドル</th> 
                <td><span id="doller-bit">${{bpi.USD.rate_float | MathRound | 1000separator}}</span><span class="small-letter">  ( ¥{{jpyUsd | MathRound1}}/USD )</span>
                </td>
                </tr>
            </tbody>
          </table> 


cssの設定

テーブルに適用するcssは、外線を非表示にし、真ん中の線のみ点線にする。

image.png
  • border-collapse: collapse; : 枠線を1重線にする(デフォルトは2重線)
  • border:none; : 枠線を非表示にする。
  • border-bottom: dashed 0.6px; : 真ん中の線のみ点線にする。
    • dottedはより細かい点線になる。
    • 上段行のbottomにのみ適用する
  • border-color: rgb(172, 172, 172); : 薄いグレー

フォントサイズや太さは適宜調整。

.css(style)
#wrapper{
  margin:60px 0;
}

.table-title{
  font-size:14px;
  color:rgb(72, 72, 72);
  font-weight: 400;
}

table{
  margin: 20px auto;
  text-align: left;
  border-collapse: collapse;
  border:none;
}
table th{
  font-size: 12px;
  font-weight: 400;
  padding:5px 10px;
}

#first-tr{
  border-bottom: dashed 0.6px;
  border-color: rgb(172, 172, 172);
}


td em{
  font-size:34px;
  font-weight: bold;
  font-style:normal;
}


.small-letter{
  font-size:12px;
}

#doller-bit{
  font-size:18px;
}



※[補足] Vue CLIで作成しているテンプレートのみにcssを適用するには、scoped属性をつける。

.css(style)
<style scorped>

</style>


2. ビットコイン価格一覧表の表示

国コードやビットコイン価格、為替の一覧を作成する。
「JPY/USD為替の取得」で取得した大元のデータの中にすべてのデータが含まれている。

image.png


2-1 小数点桁数指定フィルタの作成

データは既に取得済みなので、取得したデータを整形するため、小数点第2位表示にするフィルタを作成する。

JavaScriptのtoFixedメソッドを使用する。

数値.toFixed(桁数)

.js(script)
Vue.filter('float2', function(value) {
  return value.toFixed(2);
})


2-2 元データの確認

APIで取得したデータは複数のオブジェクトとして格納されている。

▼元データ
https://api.exchangeratesapi.io/latest

image.png

ここでは変数exchangesに格納している。

js(script)
export default {
  data: function(){
    return{
        exchanges: '',
        jpyEur: '',
    }
  },
  mounted: function(){
    //為替取得
    axios.get('https://api.exchangeratesapi.io/latest')
    .then(function(res){
        this.exchanges = res.data.rates
        this.jpyEur = res.data.rates.JPY
    }.bind(this))
    .catch(function(error){
        console.log(error)
    })
  }
}  

 

2-3 v-forによるデータ読み込み

v-forでは値とプロパティ名をそれぞれ一つづつ取り出すことができる。

v-for="(値の変数名, プロパティの変数名 in オブジェクト)" v-bind:key="key"
 ┗ プロパティ名が後ろにくる。
 ┗ 「v-bind:key="key"」:eslintのエラー対策で設置。

.html(template)
              <tr class="exchange" v-for="(exchange, country) in exchanges" v-bind:key="key">
                <th>{{country}}</th>
                <td>{{exchange * bpi.EUR.rate_float | MathRound | 1000separator }}</td>
                <td>{{jpyEur/exchange | float2 }}</td>
              </tr>

country : プロパティ名。すなわち国コードが入る。
exchange : ユーロベースの為替。
exchange * bpi.EUR.rate_float : ユーロベースの為替とユーロベースのビットコイン価格を掛け合わせたもの。現地通貨でのビットコイン価格となる
jpyEur/exchange : 対ユーロの日本円とユーロベースの為替を掛け合わせたもの。すなわち対日本円のその国の為替となる。
| MathRound : 四捨五入フィルタ
| 1000separator : 1000桁区切りフィルタ
| float2 : 小数点2桁表示

表も合わせたhtmlコードは下記になる。

.html(template)
<table id="table2" border="1">
            <tbody>
              <tr>
                <th>国コード</th>
                <th>ビットコイン価格(現地通過)</th>
                <th>為替(円)</th>
              </tr>
              <tr class="exchange" v-for="(exchange, key) in exchanges" v-bind:key="key">
                <th>{{key}}</th>
                <td>{{exchange * bpi.EUR.rate_float | MathRound | 1000separator }}</td>
                <td>{{jpyEur/exchange | float2 }}</td>
              </tr>
            </tbody>
          </table>


2-4 テーブルのスタイル調整

ヘッダーとなる、最上部の行と、最前列に色付けを行う。

.css(style)
table{
  margin: 20px auto;
  text-align: left;
  border-collapse: collapse;
  border:none;
}

table th{
  font-size: 12px;
  font-weight: 400;
  padding:5px 10px;
}


#table2{
  margin-top:100px;
  text-align: center;
}

#table2 tr:first-child{
  background: rgb(228, 228, 228);
}

.exchange th{
  background:rgba(255, 247, 215, 0.893);
}


3. 確認用コード

全体のコードは以下となる。

.html(template)
<template>
  <div>
      <h1>Bitcoin API</h1>
      <div id="wrapper">
        <div id="content-wrapper">
          <h2 class="table-title">ー 現在のビットコイン価格 ー</h2> 
          <table id="main-table"> 
            <tbody> 
              <tr id="first-tr"> 
                <th >現在値</th> 
                <td class="" id="first-td"> 
                  <em>¥{{bpi.EUR.rate_float * jpyEur | MathRound | 1000separator}}</em> <span class="small-letter">({{now}})</span> 
                </td>
              </tr> 
              <tr>
                <th>米ドル</th> 
                <td><span id="doller-bit">${{bpi.USD.rate_float | MathRound | 1000separator}}</span><span class="small-letter">  ( ¥{{jpyUsd | MathRound1}}/USD )</span>
                </td>
                </tr>
            </tbody>
          </table> 

          <table id="table2" border="1">
            <tbody>
              <tr>
                <th>国コード</th>
                <th>ビットコイン価格(現地通過)</th>
                <th>為替(円)</th>
              </tr>
              <tr class="exchange" v-for="(exchange, key) in exchanges" v-bind:key="key">
                <th>{{key}}</th>
                <td>{{exchange * bpi.EUR.rate_float | MathRound | 1000separator }}</td>
                <td>{{jpyEur/exchange | float2 }}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
  </div>
</template>
.js(scrypt)
<script>
import axios from 'axios'

export default {
  name: 'BitcoinAPI',
  data: function(){
    return{
        bpi: null,
        now: '',
        jpyEur: '',
        usdEur: '',
        jpyUsd: '',
        exchanges: ''
    }
  },
  mounted: function(){
    //ビットコイン現在価格取得
    axios.get('https://api.coindesk.com/v1/bpi/currentprice.json')
    .then(function(response){
        console.log(response.data.bpi)
        this.bpi = response.data.bpi
    }.bind(this))
    .catch(function(error){
        console.log(error)
    }),
    //現在時刻取得
    this.now = new Date().toLocaleString(),
    //為替取得
    axios.get('https://api.exchangeratesapi.io/latest')
    .then(function(res){
        console.log(res.data.rates)
        this.exchanges = res.data.rates
        this.jpyEur = res.data.rates.JPY
        this.usdEur = res.data.rates.USD
        this.jpyUsd = res.data.rates.JPY/res.data.rates.USD
    }.bind(this))
    .catch(function(error){
        console.log(error)
    })
  }
}  
</script>
.css(style)
<style scorped>
#wrapper{
  margin:60px 0;
}

.table-title{
  font-size:14px;
  color:rgb(72, 72, 72);
  font-weight: 400;
}

table{
  margin: 20px auto;
  text-align: left;
  border-collapse: collapse;
  border:none;
}
table th{
  font-size: 12px;
  font-weight: 400;
  padding:5px 10px;
}

#first-tr{
  border-bottom: dashed 0.6px;
  border-color: rgb(172, 172, 172);
}


td em{
  font-size:34px;
  font-weight: bold;
  font-style:normal;
}


.small-letter{
  font-size:12px;
}

#doller-bit{
  font-size:18px;
}

#table2{
  margin-top:100px;
  text-align: center;
}

#table2 tr:first-child{
  background: rgb(228, 228, 228);
}

.exchange th{
  background:rgba(255, 247, 215, 0.893);
}

</style>



以上。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gridsome入門 SPAを作ってみよう 【5日目 GraphQL編】

スケジュール

前提条件

  • node.js v8.3以上
  • yarn or npmが入っている(Document見るとyarnの方が推奨とのこと)
  • Gridsomeのプロジェクトを作成している

CSVからデータをインポートする

CSV用意してデータソースとして使用します。今回はCSVを使いますが、markdownで書かれたファイルなども使ったりできます。
https://gridsome.org/docs/fetching-data/#csv

gridsome.server.js
// Server API makes it possible to hook into various parts of Gridsome
// on server-side and add custom data to the GraphQL data layer.
// Learn more: https://gridsome.org/docs/server-api/

// Changes here require a server restart.
// To restart press CTRL + C in terminal and run `gridsome develop`

const {readFileSync} = require('fs');
const parse = require('csv-parse/lib/sync');
module.exports = function (api) {
  api.loadSource(async (actions) => {
    // インポートするCSV
    const input = readFileSync('./src/data/assetbalance_202008.csv', 'utf8');

    const Assets = parse(input, {
      from_line: 2,
      skip_empty_lines: true,
    });

    const collection = actions.addCollection({
      typeName: 'Assets',
    });

    for (const asset of Assets) {
      collection.addNode(asset);
    }
  })

  api.createPages(({ createPage }) => {
    // Use the Pages API here: https://gridsome.org/docs/pages-api/
  })
}

/src/data/ ディレクトリにインポートしたいCSVを配置します。
今回インポートするCSVは一行目は飛ばして、二行目からインポートするようにしました。

そしてインポートしたデータをactions.addCollection コレクションとして追加して、そのコレクションにcollection.addNode(asset); として追加していくことでGraphQLを使ってデータを扱うことができるようになります。

GraphQLとは

import-data.eb9be63.3e0083b3c8c40a300ab593b006f88025.png
画像は https://gridsome.org/docs/data-layer/#the-graphql-data-layer より引用
僕も今勉強中ですが、様々なデータソースを吸収してGraphQLを使うと便利って感じですかね。
GraphQLはAPI用のクエリ言語として開発されたっていう経緯があるみたいです。

実際にGraphQLを使ってみよう

GridsomeにはGraphQLを試せるplaygroundが用意されています。これがすごい便利。
僕みたいな初見な人でも調べながら試しながらできるのですごい助かります。
playgroundはgridsome develop を実行して、http://localhost:8080/___explore でアクセスできます。
image01.png
こんな感じの画面が表示されます。
左のクエリエディター?の画面に実行したいクエリを書いて、再生ボタンっぽいところを押すとクエリが実行されます。
GraphQLについてはこちらを参照
https://graphql.org/
もしくはplaygroundで右側についてるDOCSを開くと、実行しているクエリについても仕様を見ることができます。
image02.png

実際に作ったクエリ

query {
  tickers: allAssets(order: ASC,filter: {_0:{eq:"米国株式"}}) {
    edges {
      node {
        _1
      }
    }
  }
  valuations: allAssets(order: ASC,filter: {_0:{eq:"米国株式"}}) {
    edges {
      node {
        _4
        _8
      }
    }
  }
}

filterの指定が難しかった。色々調べてできました。
nodeの中身が一つ一つのデータなのですが、CSVの一列目が_0,二列目が_1...みたいに追加されています。
filterで_0の値が米国株式となっているものだけ取得するという形にしています。eqがイコールですね。
他にもne(not イコール)などもありました。
image03.png

GraphQLを使ってフロントエンドの処理に渡す

次は作ったクエリを実際に各ページで使うようにします。

src/pages/portfolio/index.vue
<template>
  <Layout>
    <h1>Portfolio</h1>
    <Doughnut :labels="this.formatLabels($page.tickers.edges)" :chartData="this.formatChartData($page.valuations.edges)"></Doughnut>
  </Layout>
</template>
<page-query>
query {
  tickers: allAssets(order: ASC,filter: {_0:{eq:"米国株式"}}) {
    edges {
      node {
        _1
      }
    }
  }
  valuations: allAssets(order: ASC,filter: {_0:{eq:"米国株式"}}) {
    edges {
      node {
        _4
        _8
      }
    }
  }
}
</page-query>
<script>
import Doughnut from "../../components/chart/Doughnut"
export default {
  components: {
    Doughnut
  },
  methods: {
    formatLabels: function (labels) {
      return labels.map(item => item['node']['_1']);
    },
    formatChartData: function (chartData) {
      return chartData.map(item => item['node']['_4'] * item['node']['_8']);
    }
  },
  metaInfo : {
    title: 'Hello, world!'
  }
}
</script>

<style>
.home-links a {
  margin-right: 1rem;
}
</style>

<page-query> というタグの中にGraphQLのクエリを書きます。そしてフロントエンドの処理に渡すには$pageという名前でアクセスできます。
前回までに作ったグラフのcomponentsには配列で渡しているので、配列に直すmethodsも作りました。

あとがき

いよいよお盆休みも折り返し。残り半分かー。早い。
そしてお盆休みなのに一日一回は仕事のslackくるのなに。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【0からの@keyframes】現役Vueエンジニア実装!完全オリジナルのCSSアニメーション30選(解説付き)

スクリーンショット 2020-08-12 20.50.26.png

コピペだけで作れる@keyframesを使用したCSSアニメーションを30個ご紹介します。

animation-duration、animation-timing-function、animation-direction、animation-iteration-countなどの@keyframesプロパティを要所要所で使い分けています。

コードには説明もわかりやすく書いてあるのでかなり参考になります

完全オリジナルでコピペだけで実装できてしまうお手軽なアニメーションとなっています

Webデザイン初心者の方はもちろんですが、バックエンドエンジニアの方にもとても助かる内容になっています

Webデザイナー・フロントエンジニアに興味のある方はこちらも合わせてどうぞ↓
スクリーンショット 2020-08-08 16.41.27.png

@keyframesのCSSアンイメーション30選

1. 【@keyframes×filter】画像の色合いが変化するCSSアニメーション3選

@keyframesとfilterプロパティのfilter:blur、grayscale、brightness、contrast、saturateを使用して画像の色が徐々に変化していくアニメーションとなっています。

keyframes-infinite-filter-color-change-css-animation1-300x159.png

↓参考記事は下の記事です↓

keyframes-infinite-filter-color-change-css-animation (1).png

2. 【@keyframes×filter】色が自由自在に変化するCSSアニメーション3選

@keyframesとfilterプロパティを使用して画像の色が徐々に変化していくアニメーションとなっています。

keyframes-infinite-filter-color-css-animation2-300x134.png

↓参考記事は下の記事です↓

keyframes-infinite-filter-color-css-animation (1).png

3. 進行度合いが変化するCSSアニメーション4選【@keyframes×animation-timing-functionプロパティ】

animation-timing-function: linear, ease, ease-in-out, steps()の4つのプロパティを使用してアニメーションの進行度合い(タイミング)をカンタンに指定していきます。

keyframes-infinite-timing-function-css-animation1-300x164.png

↓参考記事は下の記事です↓

keyframes-infinite-timing-function-css-animation.png

4. 【@keyframes×animation-direction】再生方向をカンタン指定!繰り返すCSSアニメーション4選

animation-direction:normal, reverse, alternate, alternate-reverseの4つを使用して再生方向をカンタンに指定していきます。

keyframes-infinite-animation-direction-css-animation3-300x153.png

↓参考記事は下の記事です↓

keyframes-infinite-animation-direction-css-animation.png

5. 【@keyframes×translate】box-shadowが効いた3D画像が移動を繰り返すCSSアニメーション3選

@keyframesのプロパティのanimation-durationやanimation-timing-function、animation-iteration-count: infinite;など5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

keyframes-infinite-translate3d-box-shadow-css-animation3-300x163.png

↓参考記事は下の記事です↓

keyframes-infinite-translate3d-box-shadow-css-animation.png

6. 【@keyframes×infinite×scale】拡大縮小を繰り返すCSSアニメーション3選【使い方も解説!】

@keyframesのプロパティのanimation-durationやanimation-timing-function、animation-iteration-count: infinite;など5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

keyframes-infinite-scale-css-animation3-300x183.png

↓参考記事は下の記事です↓

keyframes-infinite-scale-css-animation.png

7. 【@keyframes×infinite×rotate3d】360°ずっと回り続けるCSSアニメーション3選【3Dアニメーション】

@keyframesのプロパティのanimation-durationやanimation-timing-function、animation-iteration-count: infinite;など5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

transform:rotate3dで立体的な回転エフェクトとinfiniteで永遠に回転し続けるCSSアニメーションを実現。

keyframes-infinite-rotate3d-css-animation1-300x195.png

↓参考記事は下の記事です↓

keyframes-infinite-rotate3d-css-animation.jpg

8. 【@keyframes×infinite×rotate】永遠に回転し続けるCSSアニメーション3選【CSSの本気見せます】

@keyframesのプロパティのanimation-durationやanimation-timing-function、animation-iteration-count: infinite;など5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

transform:rotateの回転エフェクトとinfiniteで永遠に回転し続けるCSSアニメーションを実現しました。

keyframes-infinite-rotate-css-animation1-300x207.png

↓参考記事は下の記事です↓

keyframes-infinite-rotate-css-animation.png

9. 【初心者】@keyframesを使ったシンプルなCSSアニメーション3選【@keyframesプロパティ解説】

@keyframesのプロパティのanimation-durationやanimation-timing-functionなど5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

keyframes-simple-css-animation1-300x116.png

↓参考記事は下の記事です↓

keyframes-simple-css-animation.png

まとめ

@keyframesを使用したCSSアニメーションを30個ご紹介しました。

エンジニアの情報発信はかなり有益なので副業でブログ運営をするのがオススメです。

特に昨今ですとフリーランス需要が増えたことに伴い、プログラミングへ興味を持つ方が急激に増えていることがGoogleのアクセスデータで明らかになっています。

技術系の情報はわかりやすく再現性の高いものが多くないため今がチャンスです。

下の記事ではエンジニアが技術ブログを始めるメリットと開設手順を徹底解説しています。

・エンジニアでもブログを始めるメリットってなんだろう?
・個人ブログってQiitaと何が違うのかな?
・エンジニアだけどブログで稼げるのかな?
・どれくらいの期間継続したら稼げるようになるのかな?
・ブログ開設でかかる費用っていくらだろう?
・エンジニアだけどブログ始めてみたいけど何から始めればいいんだろう?

こんなお悩みを全て解決しています。

スクリーンショット 2020-08-12 20.18.53.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【@keyframesを5分でマスター】現役Vueエンジニア実装!完全オリジナルのCSSアニメーション30選(解説付き)

スクリーンショット 2020-08-12 20.50.26.png

コピペだけで作れる@keyframesを使用したCSSアニメーションを30個ご紹介します。

animation-duration、animation-timing-function、animation-direction、animation-iteration-countなどの@keyframesプロパティを要所要所で使い分けています。

コードには説明もわかりやすく書いてあるのでかなり参考になります

完全オリジナルでコピペだけで実装できてしまうお手軽なアニメーションとなっています

Webデザイン初心者の方はもちろんですが、バックエンドエンジニアの方にもとても助かる内容になっています

Webデザイナー・フロントエンジニアに興味のある方はこちらも合わせてどうぞ↓
スクリーンショット 2020-08-08 16.41.27.png

@keyframesのCSSアンイメーション30選

1. 【@keyframes×filter】画像の色合いが変化するCSSアニメーション3選

@keyframesとfilterプロパティのfilter:blur、grayscale、brightness、contrast、saturateを使用して画像の色が徐々に変化していくアニメーションとなっています。

keyframes-infinite-filter-color-change-css-animation1-300x159.png

↓参考記事は下の記事です↓

keyframes-infinite-filter-color-change-css-animation (1).png

2. 【@keyframes×filter】色が自由自在に変化するCSSアニメーション3選

@keyframesとfilterプロパティを使用して画像の色が徐々に変化していくアニメーションとなっています。

keyframes-infinite-filter-color-css-animation2-300x134.png

↓参考記事は下の記事です↓

keyframes-infinite-filter-color-css-animation (1).png

3. 進行度合いが変化するCSSアニメーション4選【@keyframes×animation-timing-functionプロパティ】

animation-timing-function: linear, ease, ease-in-out, steps()の4つのプロパティを使用してアニメーションの進行度合い(タイミング)をカンタンに指定していきます。

keyframes-infinite-timing-function-css-animation1-300x164.png

↓参考記事は下の記事です↓

keyframes-infinite-timing-function-css-animation.png

4. 【@keyframes×animation-direction】再生方向をカンタン指定!繰り返すCSSアニメーション4選

animation-direction:normal, reverse, alternate, alternate-reverseの4つを使用して再生方向をカンタンに指定していきます。

keyframes-infinite-animation-direction-css-animation3-300x153.png

↓参考記事は下の記事です↓

keyframes-infinite-animation-direction-css-animation.png

5. 【@keyframes×translate】box-shadowが効いた3D画像が移動を繰り返すCSSアニメーション3選

@keyframesのプロパティのanimation-durationやanimation-timing-function、animation-iteration-count: infinite;など5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

keyframes-infinite-translate3d-box-shadow-css-animation3-300x163.png

↓参考記事は下の記事です↓

keyframes-infinite-translate3d-box-shadow-css-animation.png

6. 【@keyframes×infinite×scale】拡大縮小を繰り返すCSSアニメーション3選【使い方も解説!】

@keyframesのプロパティのanimation-durationやanimation-timing-function、animation-iteration-count: infinite;など5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

keyframes-infinite-scale-css-animation3-300x183.png

↓参考記事は下の記事です↓

keyframes-infinite-scale-css-animation.png

7. 【@keyframes×infinite×rotate3d】360°ずっと回り続けるCSSアニメーション3選【3Dアニメーション】

@keyframesのプロパティのanimation-durationやanimation-timing-function、animation-iteration-count: infinite;など5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

transform:rotate3dで立体的な回転エフェクトとinfiniteで永遠に回転し続けるCSSアニメーションを実現。

keyframes-infinite-rotate3d-css-animation1-300x195.png

↓参考記事は下の記事です↓

keyframes-infinite-rotate3d-css-animation.jpg

8. 【@keyframes×infinite×rotate】永遠に回転し続けるCSSアニメーション3選【CSSの本気見せます】

@keyframesのプロパティのanimation-durationやanimation-timing-function、animation-iteration-count: infinite;など5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

transform:rotateの回転エフェクトとinfiniteで永遠に回転し続けるCSSアニメーションを実現しました。

keyframes-infinite-rotate-css-animation1-300x207.png

↓参考記事は下の記事です↓

keyframes-infinite-rotate-css-animation.png

9. 【初心者】@keyframesを使ったシンプルなCSSアニメーション3選【@keyframesプロパティ解説】

@keyframesのプロパティのanimation-durationやanimation-timing-functionなど5種類を使用して、初めての方でも理解できるように@keyframesをわかりやすく解説しています。

keyframes-simple-css-animation1-300x116.png

↓参考記事は下の記事です↓

keyframes-simple-css-animation.png

まとめ

@keyframesを使用したCSSアニメーションを30個ご紹介しました。

エンジニアの情報発信はかなり有益なので副業でブログ運営をするのがオススメです。

特に昨今ですとフリーランス需要が増えたことに伴い、プログラミングへ興味を持つ方が急激に増えていることがGoogleのアクセスデータで明らかになっています。

技術系の情報はわかりやすく再現性の高いものが多くないため今がチャンスです。

下の記事ではエンジニアが技術ブログを始めるメリットと開設手順を徹底解説しています。

・エンジニアでもブログを始めるメリットってなんだろう?
・個人ブログってQiitaと何が違うのかな?
・エンジニアだけどブログで稼げるのかな?
・どれくらいの期間継続したら稼げるようになるのかな?
・ブログ開設でかかる費用っていくらだろう?
・エンジニアだけどブログ始めてみたいけど何から始めればいいんだろう?

こんなお悩みを全て解決しています。

スクリーンショット 2020-08-12 20.18.53.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

独学半年の実務未経験がRails+Nuxt.jsでSPA作ったので見て欲しい

はじめに

アプリを作ったのはいいものの、フィードバックをくれる人がいなかったのでQiitaで紹介記事を書くことにしました。
独学で周りにアドバイスをもらえる人がいないので、改善点などどんどん指摘してくださると幸いです。

自己紹介

作者は今年の2月末ごろから独学でプログラミングを学習しています。
高校時代にほんの少しHTMLを触ったことがある程度で、前提知識はほぼありませんでした。
現在はアプリを作成しながら、10月の基本情報に向けて勉強しています。
アプリ制作は今回で2作目になります。
前作URL
前作リポジトリ

アプリ概要

これが作成したアプリです。

サイトURL
githubリポジトリ

PolPa(ポルパ)は、学習時間に応じてレベルが上がる学習記録アプリです。
全体像がわかると思うので先にERを貼っておきます。

polpa.png

機能紹介

主な機能を一部紹介します。

ゲストログイン

localhost_8080_signup.png

新規登録フォームの下からゲストアカウントでログインできます。
気軽に試すことができるので、見学しに来てください。

学習時間を記録する

time-report.gif

このアプリのメイン機能です。記録された時間に応じて経験値を獲得できます。
タグをつけてジャンル分けできます。
記録した日には草が生えます。
記録にはコメントやいいねができます。

ユーザーをフォローする

follow.gif

ユーザーをフォローすると、タイムラインにそのユーザーの記録が表示されるようになります。
他のユーザーと交流して、モチベーションを高め合いましょう!

ユーザーを検索する

search.gif

ユーザー名で検索できます。
リアルタイムに検索結果が変化します。

レスポンシブデザイン

スマホやタブレット用のデザインにも対応しているので、モバイル端末から手軽に利用できます。

他にも紹介してない機能がたくさんあるので、ゲストログインで体験してください。

作った理由

サービスとして

他の学習管理アプリを使っていて、今まで積み上げてきたものをはかる指標があればもっとモチベーションを維持しやすくなるのではないかと考え、「学習時間を記録するとレベルが上がる」という要素をプラスした学習管理アプリがあれば面白いのではないか、と開発を始めました。

個人として

個人的には、Vue.jsとRailsを使って何かを作りたかったから開発を始めたという理由もあります。
作る前はこんな程度のアイデアで開発を始めてもいいのだろうかと思っていましたが、開発を進めていくうちに少し愛着が湧いてきました。

技術周りの話

使用している主な技術やリソース

  • Ruby、Rails ... バックエンド
  • Vue.js、Nuxt.js ... フロントエンド
  • Vuetify ... UIフレームワーク
  • PostgreSQL ... データベース
  • Docker、Docker-compose ... コンテナ仮想化
  • Git、GitHub ... バージョン管理システム
  • Firebase ... ログイン認証・ホスティング
  • heroku ... API用サーバー

Rails

バックエンドにはRailsを使用しています。Railsは学習期間が最も長く、前作でも使用しています。
新しく作るアプリは新しい要素を追加したいと思ったので、バックとフロントで別のフレームワークを使用する手法を取ることにしました。

Vue.js、Nuxt.js

Vue.jsは以前から興味があり、Railsとの共存も容易だったため、学習を開始しました。
Vue.jsは書籍一冊学習したのみだったので、雰囲気しか理解していない状態からコードを書き始めました。
Nuxt.js自体は開発を始めてから初めて触りました。

Vuetify

フロントのデザインはほとんどVuetifyに頼っています。アプリに必要なデザインコンポーネントが一通り揃っているので、一から作るにはめんどくさいデザインも簡単に実装できました。
種類が豊富なので、Vuetifyの公式リファレンスを見るだけで楽しいです。

Firebase

ログイン認証にはFirebaseを用いています。初めての開発手法だったため、自力で安全な認証・認可を実装できないと判断し、Firebaseを使用することにしました。

一人で開発して感じたこと

個人で開発をしていく上で良かったことと、つらかったこと・反省点をいくつかまとめてみます。

良かったこと

前作を制作した時も感じていましたが、アプリ制作は本当に勉強になります。
特に独学だとすべてのエラーを自力で解決しなければならないので、デバック力や問題解決能力が磨かれます。
一人で開発するとWeb開発の技術が全般的に必要になるので、次に勉強したい分野が明確になるのもいい点だと思います。

つらかったこと・反省点

  • エラーの解決方法がわからないとストレスがたまる
  • 開発するときのルールを決めておかないと徐々に雑になる
  • あれもこれもと機能を追加しているとキリがない

コードが予想に反する動きをして半日潰れたなんてことは日常茶飯事だったので慣れはしましたが、目に見える成果が全く得られないというのはストレスがたまります。ネットで検索してみてもそれらしい情報が全く出てこなかった時は本当に絶望します。
ただ、良かった点にも書いているようにメリットとは表裏一体です。
なんとか解決してきたので、自分の力にもなっているのかなと思います。

最初に張り切って、「今回はこの方法にしたがってコーティングして、この手法を使って開発を進めるぞ!」 なんて思っても大体続きませんでした。だんだん雑になってきて、めんどくさいからいいか、一人だからいいかとなりがちでした。次回があれば、ルールの徹底を意識したいと思います。

これからについて

もっと追加したい機能があるので時間があればアップデートしたいと思っています。
10月中旬の基本情報に向けてJavaを勉強するつもりなので、しばらくは時間がないと思いますが、アプリの完成度を高ていきたいのでフィードバックなどよろしくお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

現役Vueエンジニアが参考にしているフロントエンド素材サイトまとめ4選

今回の記事ではフロントエンド開発で参考にしているサイトを紹介していきます。
どれも動くCSS素材やコピペだけで簡単に実装できる素材がまとまっています。

気に入ったサイトを自己判断で参考にしてみてください。

TwinzLabo

コピペだけで作れるデザインレシピを公開しています。動きのあるデザインやオシャレなWebデザインなど様々な記事があるのでおもちゃ屋さんに来たかのように楽しめます。記事に使用しているアニメーションはVue環境で作成されているので普段Vueで開発している方はコピペだけできれいに反映させることができて便利です。記事で紹介されているコードひとつひとつに詳しく解説がついているので初心者にはありがたいかと思います。

スクリーンショット 2020-08-12 20.09.09.png


Free Frontend

By using freefrontend.com you accept our cookies and agree to our privacy policy, including cookie policy. Read privacy policy. OK! Free Frontend. HTML + CSS. HTML Examples · CSS Examples · Bootstrap Examples · Speed Code.
いわゆるCodePenのまとめサイトです。コピペOKですがコードにはライセンスがあるので気をつけて使ってください。参考になるデザインは多いので初心者の方には刺激になり面白いかと思います。

スクリーンショット 2020-08-12 20.19.51.png


サルワカ

サルワカはあらゆることを分かりやすく解説するメディアです。フロントエンドを学習している方ならだれもが知っているサイト。ガンガン動くようなアニメーションは少ないですが、基礎的なデザインやCSSのエフェクトを学習したい方にはぴったりのサイトです。無料でフロントエンドを学習したい!という方は是非。

スクリーンショット 2020-08-12 20.25.39.png


1stWebDesigner

海外のサイトです。Webデザインで参考になる素材が多く見ているだけでも楽しいです。頭が湧いてきた際に眺めているとアイデアが湧いてくるのでいつも感謝しています。ただ、ちょっとページの読み込みが重いのが難点。。

スクリーンショット 2020-08-12 20.27.59.png

他にもいくつかありますが、最近特に参考にしているサイトはこんな感じです。
初心者の学習の励みになれたら本望です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

現役Vueエンジニアが参考にしているフロントエンド素材まとめサイト4選

今回の記事ではフロントエンド開発で参考にしているサイトを紹介していきます。
どれも動くCSS素材やコピペだけで簡単に実装できる素材がまとまっています。

気に入ったサイトを自己判断で参考にしてみてください。

TwinzLabo

コピペだけで作れるデザインレシピを公開しています。動きのあるデザインやオシャレなWebデザインなど様々な記事があるのでおもちゃ屋さんに来たかのように楽しめます。記事に使用しているアニメーションはVue環境で作成されているので普段Vueで開発している方はコピペだけできれいに反映させることができて便利です。記事で紹介されているコードひとつひとつに詳しく解説がついているので初心者にはありがたいかと思います。

スクリーンショット 2020-08-12 20.09.09.png


Free Frontend

By using freefrontend.com you accept our cookies and agree to our privacy policy, including cookie policy. Read privacy policy. OK! Free Frontend. HTML + CSS. HTML Examples · CSS Examples · Bootstrap Examples · Speed Code.
いわゆるCodePenのまとめサイトです。コピペOKですがコードにはライセンスがあるので気をつけて使ってください。参考になるデザインは多いので初心者の方には刺激になり面白いかと思います。

スクリーンショット 2020-08-12 20.19.51.png


サルワカ

サルワカはあらゆることを分かりやすく解説するメディアです。フロントエンドを学習している方ならだれもが知っているサイト。ガンガン動くようなアニメーションは少ないですが、基礎的なデザインやCSSのエフェクトを学習したい方にはぴったりのサイトです。無料でフロントエンドを学習したい!という方は是非。

スクリーンショット 2020-08-12 20.25.39.png


1stWebDesigner

海外のサイトです。Webデザインで参考になる素材が多く見ているだけでも楽しいです。頭が湧いてきた際に眺めているとアイデアが湧いてくるのでいつも感謝しています。ただ、ちょっとページの読み込みが重いのが難点。。

スクリーンショット 2020-08-12 20.27.59.png

他にもいくつかありますが、最近特に参考にしているサイトはこんな感じです。
初心者の学習の励みになれたら本望です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

現役Vueエンジニアが参考にしているフロントエンド素材まとめおすすめサイト4選

今回の記事ではフロントエンド開発で参考にしているサイトを紹介していきます。
どれも動くCSS素材やコピペだけで簡単に実装できる素材がまとまっています。

気に入ったサイトを自己判断で参考にしてみてください。

TwinzLabo

コピペだけで作れるデザインレシピを公開しています。動きのあるデザインやオシャレなWebデザインなど様々な記事があるのでおもちゃ屋さんに来たかのように楽しめます。記事に使用しているアニメーションはVue環境で作成されているので普段Vueで開発している方はコピペだけできれいに反映させることができて便利です。記事で紹介されているコードひとつひとつに詳しく解説がついているので初心者にはありがたいかと思います。

スクリーンショット 2020-08-12 20.09.09.png


Free Frontend

By using freefrontend.com you accept our cookies and agree to our privacy policy, including cookie policy. Read privacy policy. OK! Free Frontend. HTML + CSS. HTML Examples · CSS Examples · Bootstrap Examples · Speed Code.
いわゆるCodePenのまとめサイトです。コピペOKですがコードにはライセンスがあるので気をつけて使ってください。参考になるデザインは多いので初心者の方には刺激になり面白いかと思います。

スクリーンショット 2020-08-12 20.19.51.png


サルワカ

サルワカはあらゆることを分かりやすく解説するメディアです。フロントエンドを学習している方ならだれもが知っているサイト。ガンガン動くようなアニメーションは少ないですが、基礎的なデザインやCSSのエフェクトを学習したい方にはぴったりのサイトです。無料でフロントエンドを学習したい!という方は是非。

スクリーンショット 2020-08-12 20.25.39.png


1stWebDesigner

海外のサイトです。Webデザインで参考になる素材が多く見ているだけでも楽しいです。頭が湧いてきた際に眺めているとアイデアが湧いてくるのでいつも感謝しています。ただ、ちょっとページの読み込みが重いのが難点。。

スクリーンショット 2020-08-12 20.27.59.png

他にもいくつかありますが、最近特に参考にしているサイトはこんな感じです。
初心者の学習の励みになれたら本望です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

googleの翻訳機能にやられた

反省したので記事に残します・・・。
これを初記事にする事で肝に銘じる

結論

@vue/cli で作成した index.html を放置すると痛い目見る

事の発端

顧客のとある要件で必要になったから、会社で開発しているシステムの一部を vue.js でリプレースし、納品した
納品後の検修の際に画面の表示がおかしいよと言われた(画面のどこがおかしいかは教えてくれなかったぴえん)

調査するも手持ちの Mac,windows,android,iOS のどれでみても再現できなかった

上司と二人で頭を抱えていると別の社員から再現できたと言われた・・・

謎めいた現象

  • 謎の日表示

v-calendar(https://vcalendar.io/)を利用してカレンダーを表示している
なぜか 26、27、29 だけ日の表記がついていた

スクリーンショット 2020-08-12 16.44.01.png

  • 謎の年表示

本来金額を表示している部分(単位・変換なし)の 1000 以上の値がなぜか年表記になる

スクリーンショット 2020-08-12 16.48.48.png

閃いた決定打

ふとタイトルを見ると
本来英語なはずが

例:coffee-latte

がカタカナに変換されていた

例:コーヒーラテ

もしかして、翻訳されてるのでは・・・?

ついに判明

結局のところ原因は凡ミス

index.html の lang が en になっていただけだった

<html lang="en"></html>

正しくは

<html lang="ja"></html>

一部の環境でしか再現しなかったのは
google の翻訳機能で常に日本語に翻訳に設定しているかいないかの違いだった

大反省・・・

自動生成された index.html を大して確認もせずそのまま放置していたのが原因でした

@vue/cli で作成した index.html を放置すると痛い目を見ます
良い子はちゃんと確認しようね

あとなんでカレンダーの26,27,29の部分のみ日がついたのか、調べてもよくわからなかったのでもしわかる方がいたら教えてください、、、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vuetify + Veevalidate 3 + Jest(test:unit) を動くところまでもってく

Vuetify

本家のドキュメントのtestに関する章を参照
https://vuetifyjs.com/ja/getting-started/unit-testing/

Vuetifyの組み込み方は、specの最初に、次のように書く。

import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify)

本家のドキュメントに次のような記述がありますが、この方法でlocalVueにvuetifyを読み込んでもうまくいきませんでした。

  //うまくいかなかった方法
  let vuetify

  beforeEach(() => {
    vuetify = new Vuetify()
  })

  it('should have a custom title and match snapshot', () => {
    const wrapper = mount(CustomCard, {
      localVue,
      vuetify,
      propsData: {
        title: 'Foobar',
      },
    })

Veevalidate

今回使用したのはVeevalidate 3.3.9 です。2系だと記述が違うので気を付けてください。

本家のドキュメントのtestに関する章を参照
https://logaretm.github.io/vee-validate/advanced/testing.html#asynchronous-testing

次のような記述例がありますが、$refを使った方法はうまく動作しませんでした(テンプレートもドキュメントと同じものにしてみたんですが…)

const error = wrapper.vm.$refs.provider.errors[0];

実際のinputやエラーを出力するDOMを見つけて値セットしたり、エラーメッセーを確認する方法は動作しました。以下の方法を参照してください。

値のセット方法

次のテンプレートの場合

<ValidationProvider name="email" v-slot="{ errors }" id="ID1" rules="required|email">
<v-text-field
  id="input_email"
  v-model="email"
  :error-messages="errors"
  label="E-mail"
  required
></v-text-field>
</ValidationProvider>

次のような方法で、値をセットして、エラーメッセージを確認できます

inputにIDを付けて直接見つける方法

wrapper.find('input_email').setValue('aaa');

ValiidationProviderにIDを付けて見つける方法

(エラー出力を得る方法と統一できるのでお勧め)

wrapper.find('#ID1').find('input').setValue('aaa');

バリデーション結果のチェック方法

const errorEl = wrapper.find('#ID1').find('.v-messages__message');
expect(errorEl.text()).toBe('Email must be valid');

Vuetifyが組み込まれているかの確認方法

どこまで動作してるのか全く掴めず、デバックに非常に苦労しました。
Vuetifyが取り込まれていないとレンダリングが実行されず、バリデーションの動作が成功するはずもありません。
動作確認として、次のコードを含んだテストを実行して、作成されたスナップショットファイルを確認する(スナップショットファイルが存在しない時は、結果をファイルに保存する動作になる。存在する時は、比較する動作)のがお勧めです

expect(wrapper.html()).toMatchSnapshot()

※余談
スナップショットを更新(正解データを更新する)時には、次のコマンドを実行

npm run test:unit -- --updateSnapshot

エラーと対処方

SyntaxError: Unexpected token 'export'

Veevalidateや、Vuetifyのモジュールの中で、SyntaxErrorが出ます。
これは、jestがTypescriptの記述を認識していないために発生しています。
paclage.jsonのtransformIgnorePatternsに"/node_modules"のtransformを行わない設定がある為に起きています。この行を削除するか、次の例のように、vurtifyとvee-validateディレクトリは除く記述にします。

  "jest": {
    "transformIgnorePatterns": [
      "<rootDir>/node_modules/(?!(vuetify|vee-validate))"
    ],
    "preset": "@vue/cli-plugin-unit-jest"
  }

specファイル全体

import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify)

import flushPromises from 'flush-promises';
import { mount, createLocalVue } from '@vue/test-utils'
const localVue = createLocalVue()

import AddEmail from '@/views/AddEmail.vue'

describe('AddEmail.vue', () => {
  // バリデーションエラーのテスト開始
  const mount_AddEmail = function() {
    return mount(AddEmail, {
      localVue,
      sync: false
    })
  }

  it('snapshot check', async () => {
    const wrapper = mount_AddEmail()
    expect(wrapper.html()).toMatchSnapshot()
  })
  it('dupcheck error if input "mike" in input of name', async () => {
    const wrapper = mount_AddEmail()
    wrapper.find('#ID2').find('input').setValue('mike');    
    await flushPromises();
    const errorEl = wrapper.find('#ID2').find('.v-messages__message');
    expect(errorEl.text()).toBe('同じ名前は登録できません');
  })
  it('email address format check', async () => {
    const wrapper = mount_AddEmail()
    wrapper.find('#ID1').find('input').setValue('aaa');    
    await flushPromises();
    const errorEl = wrapper.find('#ID1').find('.v-messages__message');
    expect(errorEl.text()).toBe('Email must be valid');
  })
  it('required condition of name', async () => {
    const wrapper = mount_AddEmail()
    wrapper.find('#ID2').find('input').setValue('');    
    await flushPromises();
    const errorEl = wrapper.find('#ID2').find('.v-messages__message');
    expect(errorEl.text()).toBe('name can not be empty');
  })
  it('required condition of email', async () => {
    const wrapper = mount_AddEmail()
    wrapper.find('#ID1').find('input').setValue('');    
    await flushPromises();
    const errorEl = wrapper.find('#ID1').find('.v-messages__message');
    expect(errorEl.text()).toBe('email can not be empty');
  })
})
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vuejs + axios + Slack Incoming WebHooks

フロントのJS(axios)からIncoming WebHooksにリクエストするさいのメモ
CORSで怒られてたところ、AuthorizationとContent-Typeヘッダーを削除することで上手くいった。

    var params = {
      'blocks': [{
        'type': 'divider'
      }, {
        'type': 'section',
        'text': {
          'type': 'mrkdwn',
          'text': 'message'
        }
      }]
    }
    async function slack (payload) {
      var WEBHOOK_URL = 'https://hooks.slack.com/services/*******/*******/*********'
      const res = await axios.post(WEBHOOK_URL, JSON.stringify(payload), {
        withCredentials: false,
        transformRequest: [(data, headers) => {
          delete headers.common.Authorization
          delete headers.post['Content-Type']
          return data
        }]
      })
      return res.data
    }

    slack(params).then(console.log)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】Vue+API Gateway+LambdaでサーバレスWebアプリを作った際に遭遇した問題

概要

「AWSを使って、サーバレスアプリを作りたい!」と思い実践したのですが、Lambda関連で結構な壁があったので備忘がてら残します。

ハマりポイントは以下3つ。

  • LambdaのResponseは特定のJSON形式でないとNGな話
  • API連携の際に、CROS Policyでエラーになった話
  • APIに認証を噛ませる際は、accessTokenではなくidTokenを使用する話

LambdaのResponseは特定のJSON形式でないとNGな話

今回はフロントサイドはvueで作成、そこからAPIGatewayを通してLambdaのFunctionを呼び出すという構成でした。
このFunctionの返却の仕方は何でもよい訳ではなくJSONの形式が決まっています。

参考:https://aws.amazon.com/jp/premiumsupport/knowledge-center/malformed-502-api-gateway/

以下は、Lambdaを通してTwitterに投稿する関数の例です

exports.handler = (event, context, callback) => {
    let date = new Date();
    twitter_client.post('statuses/update', {status: 'テスト投稿。from lamda ' + date},  function(error, tweet, response){
        if(error) {
            //エラーハンドリング
        }
        callback(null, JSON.stringify(response));
    });
};

関数単体はテスト時に動いても、上記のような正しい形式でないと、実際のフロントからの実行時には500エラーを返すので注意。

API連携の際に、CROS Policyでエラーになった話 

「JSONを返す必要があるということはわかったぜ!これでオッケーや!」と思ったら、まだ駄目でした。
今度はフロント側でエラーになりました。。。ブラウザのF12コンソールでエラーの内容を確認すると
「Access to XMLHttpRequest at 'http:/~' from origin 'http://localhost:8080' has been blocked by CORS policy:
…」と書いてありました。
あぁーCROSね、なんかAPIGatewayで設定があった気がするなーと思いいろいろググります。

※CROSについては以下の記事が参考になりました。
https://qiita.com/att55/items/2154a8aad8bf1409db2b

結論から言うと、以下のように設定するのが正解でした。
レスポンスのヘッダーに
Access-Control-Allow-Headers (使用するHeadersの値を追加)
Access-Control-Allow-Origin (許可するリソースを追加)
Access-Control-Allow-Credentials (これはなくてもいいかも)
Access-Control-Allow-Methods (必要なメソッドを追加)
を追加します。
image.png

lambdaの関数のレスポンスに直接書いているやり方もありましたが、
調べて実際に動かしたところこれでも大丈夫。(ケースバイケースだが多分ほとんどの場合これがベターな気がする)

APIに認証を噛ませる際は、accessTokenではなくidTokenを使用する話

これはハマったというほどではなかったが、少し勘違いがあったので記載。
上記の問題でAPI通信は問題なく通るようになったが、APIには認証をかけたほうがよい。

認証のかけ方もいくつか方法があるが、今回はcognitoユーザプールを使った。
※cognitoを使ったログイン機能を実装していることが前提です。

手順としては
1.APIgatewayのコンソールからAuthorizersを作成
2.使用するAPIに適用する
の2 STEEP(めちゃ簡単)
image.png

フロントのコードは以下のような感じで実装

App.vue
import { Auth } from 'aws-amplify'
import axios from 'axios'

let cognitoUser = await Auth.currentAuthenticatedUser()
this.signedIn = true
this.username = cognitoUser.username
let token = cognitoUser.signInUserSession.idToken.jwtToken;
console.log(cognitoUser.signInUserSession);

…中略…
APIfunction(){
        axios
          .get('APIのURL',
            {
              headers: {
                Authorization: token
              }
            }
          )
          .then(function (response) {
            // handle success
            console.log(response);
            alert("success");
            alert(response);
          })
          .catch(function (error) {
            // handle error
            console.log(error);
            alert("error");
            alert(error);
          })
    }

signInUserSessionの中にはaccessTokenという似たプロパティもあるが、こっちではなくidTokenを使用した点に注意。
※accessTokenでも認証機能を作ることはできるかも知れませんが、詳細は調査しきれず…(だれか知っている人がいたら教えてください…)

まとめ

AWSを使いこなすまでの道のりは遠い…
一方で使いこなすと非常に便利だということも実感できた。前進あるのみ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む