20191024のvue.jsに関する記事は7件です。

Nuxt.jsにvue-konvaを追加する

前提

Nuxt.jsプロジェクトは、すでに作成されていることします。
Nuxt.js 3向けです。

konva、vue-konvaとは

konvaは、HTML5 CanvasのJavaScriptのフレームワークです。
Vue.js向けに、kovaをコンポーネント化したvue-konvaというものがあります。

vue-konvaの追加方法

慣れた方であれば、当たり前で、簡単でしょうが、
初めてだと難しいと思われるので手順を残しておきます。

1. konvaをインストール

nuxt.jsのプロジェクトがあるところでコマンドを実行してください。

npm install vue-konva konva --save

yarnコマンドを使用している場合は下記を実行してください

yarn add vue-konva konva

2. plugins/vue-konva.jsファイルを作成

plugins/vue-konva.js
import Vue from 'vue';
import VueKonva from 'vue-konva'

Vue.use(VueKonva)

3. nuxt.config.jsのpluginsキー内にファイルパスを追加

pluginsと書かれた箇所を見つけて次のように追加してください。

nuxt.config.js
/*
  ** Plugins to load before mounting the App
*/
   plugins: ["~/plugins/vue-konva"],
/*
   ** Nuxt.js dev-modules
*/

4. pages/index.vueに、下記を記述し動作確認

pages/index.vue
<template>
  <v-stage :config="configKonva">
    <v-layer>
      <v-circle :config="configCircle"></v-circle>
    </v-layer>
  </v-stage>
</template>

<script>
export default {
  data () {
    return {
      configKonva: {
        width: 200,
        height: 200
      },
      configCircle: {
        x: 100,
        y: 100,
        radius: 70,
        fill: "red",
        stroke: "black",
        strokeWidth: 4
      }
    };
  }
};
</script>

<style>
</style>

どのコンポーネントに記述しても大丈夫です。

5.ブラウザでアクセスし動作確認

http://localhost:3000 にアクセスし、次のような円が出たら成功です。
(背景の色は、白になっていると思います)

2019-10-24_19h10_43.png

背景の色は、Nuxt.jsのプロジェクトの設定(UIコンポーネントのインストール状況)によって変わります。
私の場合、Nuxt.jsのプロジェクト作成時に、Vuetifyを入れているので黒になってます。

window is not undefindedとエラーメッセージが出たとき

<client-only></client-only> で、囲んでください。
SSR モード だと出てしまいます。

<client-only placeholder="Loading...">
    <v-stage :config="configKonva">
      <v-layer>
        <v-circle :config="configCircle"></v-circle>
      </v-layer>
    </v-stage>
</client-only>

最後に

他のプラグインも、同じ手順で追加可能です。
楽しいNuxt.jsライフを!
ではまた。

参考

https://ja.nuxtjs.org/guide/plugins/
https://konvajs.org/docs/vue/

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

buefyのデフォルトアイコンをFont-Awesomeにする

Vue.use(Buefy, {
    defaultIconPack: 'fas',
    // ...
})

これだけでよかった。
https://buefy.org/documentation/constructor-options/

  • 全てのフォームにちまちまとicon-pack="fas"を仕込まなくてもよかった。
  • b-numberinputのプラスマイナスのアイコンを変更できなくて絶望しなくてもよかった。
  • b-numberinputのソースを追いかけて「iconPack="fas"ならいけるやん…!」とか感動しなくてもよかった。
  • 冷静に考えてできないわけないだろ、と思われるものはちゃんと調べよう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AxiosでBacklog APIを使用してGET・POSTする

概要

Nuxt×axiosでBacklogAPIを使用して課題を追加したりする際、結構引っかかった個所が多かったので
リファレンスをかみ砕いたものをメモしておきます。

BacklogAPIを使用する上で共通で必要な情報

space

ご使用のBacklogのURL https://[ココの部分]/dashboardになります。

apikey

「個人設定」→「API」で新しいAPIキーを作成することができます。

課題の追加

まずは公式リファレンスを読んでみましょう。
公式リファレンスにある通り、必須項目は下記の4つ。

パラメータ名 内容
projectId 課題を追加するプロジェクト
summary 追加する課題名
issueTypeId 課題の種別
priorityId 優先度

実際にPOSTされるURL

https://[space名]/api/v2/issues?apiKey=APIキー&projectId=課題を追加するプロジェクト&summary=追加する課題名&issueTypeId=課題の種別&priorityId=課題の重要度

Code

<script>
import axios from 'axios'

export default {
  methods: {
    addTask () {
      // 送信するパラメータ類
      const sendData = new URLSearchParams()
      sendData.append('apiKey', 送信者のAPIキー)
      sendData.append('projectId', 課題を追加するプロジェクト)
      sendData.append('summary', 課題名)
      sendData.append('issueTypeId', 課題の種別)
      sendData.append('priorityId', 優先度)
      // ここまで必須項目

      sendData.append('description', 課題詳細)
      sendData.append('assigneeId', 課題担当者)
      sendData.append('actualHours', 予定工数)
      sendData.append('startDate', 開始日)
      sendData.append('dueDate', 完了日)

      axios.post('https://[space名]/api/v2/issues?' + sendData)
        .then((res) => {
          console.log('【Add Task】', res)
        })
        .catch((error) => {
          console.log('【Add Task】', error)
        })
    }
  }
}
</script>

axios.postでパラメータを使用する場合、本来ならば下記のような記載方法で
行けるはずなのですがなぜか上手くいかず、上記のように設定したところ送信できました。

axios.post('https://[space名]/api/v2/issues', sendData)

注意点 :warning:

  • 使用しているAPIキーの発行アカウントが管理者かどうかでできる制限が結構変わります。
  • カスタム属性を設置していて、その項目が必須になっている場合があるので注意しましょう。
    僕はこれになかなか気付かず何時間も無駄にしました…:cry:
  • 必須項目である【課題の種別】は同じ名前でもプロジェクトごとにキーが違います。

種別一覧の取得

先ほどの課題の追加の際、必須になってくる【種別一覧】を取得してみましょう。
公式リファレンスはこんな感じ。

パラメータ名 内容
projectIdOrKey プロジェクトのID または プロジェクトキー

実際にGETを行うURL

https://design-ac.backlog.com/api/v2/projects/[プロジェクトのID または プロジェクトキー]/issueTypes?apiKey=APIキー

リファレンスにあるURLの/api/v2/projects/:projectIdOrKey/issueTypes
:projectIdOrKeyの部分に【課題種別一覧を取得したいプロジェクトのIDまたはキー】を
入力したURLという意味になります。僕も今回初めて知ったのですが、:〇〇
そのまま記載するという意味ではありません。

Code

<script>
import axios from 'axios'

export default {
  methods: {
    getTaskTypes () {
      axios.get('https://[space名]/api/v2/projects/[プロジェクトID or Key]/issueTypes?apiKey=送信者のAPIキー')
        .then((res) => {
          console.log('【issuetype】', res)
        })
        .catch((error) => {
          console.log('【issuetype】', error)
        })
    }
  }
}
</script>

上記で一覧が取得でき、consoleにデータが出力されるはずです。
今回はapikeyをそのままurlに打ち込むタイプでGETを行いましたが、問題なく動作しました。

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

Vue スクロールを検知してDOM要素を消す(非表示)

やりたいこと

横のスクロールを検知し、スクロールできなくなった所で、ある要素を消す。
下記の記事が参考になるので飛んでください✈️

どうやるか?

①ref属性を使い、DOM要素にアクセスできるようにする。
②スクロールイベントを追加する。
③イベント発火時の処理を書く。

コード

<template>
  <div>
    <card ref="content">
       <button v-show="visibleButton"></button>
    </card>
  </div>
</template>

<script>
export default {
  data() {
    return {
      visibleButton: false
    };
  },

  // DOMの生成が完了後(ref属性が割り当てられるのを待つ)、スクロールイベントを追加する
  mounted() {
    window.addEventListener('scroll', this.handleScroll);
    this.$refs.content.addEventListener('scroll', this.handleScroll);
  },

  // インスタンス破棄時に、イベントも削除する
  destroyed() {
    window.removeEventListener('scroll', this.handleScroll);
    this.$refs.content.removeEventListener('scroll', this.handleScroll);
  },

  methods: {
    /**
     * スクロールした際に、$ref.contentのwidthを取得し、ボタンの表示・非表示を制御する
     */
    handleScroll() {
      this.$refs.content.scrollLeft <= 0
        ? (this.visibleButton = false)
        : (this.visibleButton = true);
    }
  }
};
</script>

参考資料

ref属性の主な目的は、親の$ refs属性のキーとしてDOM要素を選択可能にすることです。
たとえば、ref = “input”を指定したinput要素は、親としてDOM要素を公開します(ここではcurrency-> input thisです)。 。

(引用の引用)
- 【Vue.js】スクロールでDOM操作する(消えるタイトル編) すごく参考になりました?‍♂️
- Vue Scroll Sample すごく参考になりました?‍♀️

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

Javascriptの同期/非同期って何?関数Promise、Async、Await

はじめに

皆さん、こんにちは!Webシステム開発エンジニアの蘭です!
今日はJavascriptの同期/非同期関数:【Promise、Async、Await】について語りたいと思います。

・そもそも同期と非同期処理って何?

結論から言いますと、

・同期処理:あるタスクが実行している間、他のタスクの処理は中断される方式です。

・非同期処理:あるタスクが実行をしている際に、他のタスクが別の処理を実行できる方式になります。

想像してみましょう

 仮にあなたは今SNSのユーザーだとします、普段は忙しいパパでも、休みを取り、家族との記念で海外旅行に行きました。
 写真撮影はいいカメラを使い、高画質な画像やビデオばかり。
 そしてそれをSNSに投稿した後、ネットのせいか30分ぐらい処理待ちの状態、画面も真っ白になり、不安しか積もるばかりで、投稿処理が終わらないと何もできない...

何故ユーザーがずっと処理待つことになるのか

上記の例で見てみよう

■今までのフロントエンド処理

  1. 投稿画面表示:ブラウザーからサーバー画面要求(GET)やデータ送信(POST)し、サーバーからHTMLが返却され、画面を表示。
  2. SNSに投稿:ブラウザーからサーバー画面要求(GET)やデータ送信(POST)します。
  3. 写真や投稿内容の保存:サーバーでデータの新規追加処理が行われます。
  4. 投稿内容をSNSに表示:サーバーで処理が完了後、HTMLをブラウザーに返却し、ブラウザーにHTMLを描画して投稿内容を画面に表示。

alt
マルチページアプリケーションの通信パターンはこのワンセットの繰り返しです。
これではサーバーの実行が完了しないと、画面の更新はされない状態になり、ユーザーは画面が更新されるまで、ずっと待つ状態となります。

■近年はSPAで非同期処理

Webサイトで近年SPA(シングルページアプリケーション)の導入が多くなりました。何故なら非同期に複数の処理ができるからです。

  1. 投稿画面表示:ブラウザは最初に画面を要求し、サーバは HTML を返却し、画面表示。
  2. バックで投稿処理をし、同時に画面更新:ページ遷移せずに、Ajax等でサーバーにデーター要求や送信をし、同時にJavascriptにより画面の更新部分だけを書き換えて、ユーザーは更新後の画面が見られます。
  3. 後はAjaxでサーバーのやり取り結果を待つ事になりますが、画面が真っ白等、画面更新処理が中断されることは有りません。

以下の利点があります。
  ・更新部分だけ書き換えるので、画面更新処理向上
  ・複数処理を同時に行うため、処理速度が速くなる
  ・ユーザーの使用感も改善

alt

もちろん、同期と非同期処理にはメリットとデメリットがあります。
こちらは開発内容に応じて調整しましょう。
  同期処理と非同期処理

Javascriptの同期/非同期

以下の内容をこちらを引用。

簡単な同期処理の例を見てみましょう。

同期.js
console.log(1);
console.log(2);
console.log(3);

ログを3つ表示するだけのシンプルな処理です。
3つの関数上からはlog(1)、log(2)、log(3)の順番に処理されます。

1
2
3

上から順に処理していくのは同期処理です。

非同期処理

非同期.js
console.log(1);
setTimeout(function(){console.log(2)}, 1000); 
//console.log(2)の処理を1秒後実行する
console.log(3);
1
3
2

 ・先ず、こちらsetTimeout()はコールバック関数と呼びます。
Javascriptではコールバック関数は非同期処理になります。(※コールバック関数は後ほど説明します。)
 ・setTimeout()が呼び出された後、内部の関数(console.log(2))は別世界、別次元で動いてると思ってください。ですのでsetTimeout()と別に関数内部は非同期に処理されます。setTimeout()は呼び出すだけで、表は実行完了となります。
 ・setTimeout()は内部の処理は別として実行完了となり、次のconsole.log(3)の処理を開始します。
 ・最後にsetTimeout()内部で、一秒後にconsole.log(2)が実行された為、実行完了時間がconsole.log(3)より遅く完了しました。
 ・console.log(2)実行完了後に2という結果が表示されました。

⇛console.log(3)を処理していると同時にconsole.log(2)を処理する、これが非同期処理です。

コールバック関数って何?

・別の関数に呼び出してもらうための関数
・簡単に言うと関数の引数に関数が指定されてる。

コールバック.js
function Callback(B){
  ...
}
//関数Bが関数Aの引数に指定されてる
function B(){
  ...
}

ここで、何?関数を引数として指定ってどういう意味?

実はJavascriptでは数字、ブーリン、文字、配列、関数全て値です。

以下の内容はこちらを引用。

値.js
const numValue = 100;
const strValue = "私は値です!";
const boolValue = true;
const arrayValue = [1, 2, 3];
const objValue = { key: 'value' };
関数も値.js
const addFunc = function(a, b){
   return a + b;
}
console.log(addFunc(2, 3));
//5が表示される。
//addFuncも値で、引数として指定できます。

ここで注意、関数を値として扱う時は括弧()は付けません

関数を値として指定する時、括弧付けない.
// 自分で定義する関数
function add(a, b) {
  return a + b;
}

// 定義した関数を変数に入れる
const addFunc = add; // カッコはつけない!

// JavaScriptに標準でついてる関数でもできる
const myMax = Math.max; // max関数をmyMaxという変数に入れる

// 呼び出してみる
console.log(add(1, 2), addFunc(1, 2)); // どっちも3になる
console.log(Math.max(1, 2), myMax(1, 2)); // どっちも2

⇛関数に括弧があれば処理の呼び出しになり、括弧がなければ値として扱われます。

では、本題に戻ります。
コールバック関数とは高階関数に渡すための関数です。

コールバック関数
// 関数を2回実行する関数!!
function doTwice(func) {
  func(); // 1回目!
  func(); // 2回目!
}

// あいさつを2回実行する
doTwice(sayHello);

//あいさつをする
function sayHello() {
  console.log('Hello!');
}

上記を見ますとdoTwiceに関数sayHello()が引数として指定されてますね、このdoTwiceがコールバック関数です。
これで何故setTimeout()がコールバック関数なのか理解できましたね。

非同期でコールバック関数地獄

以下の内容はこちらを引用。

先ず非同期のコールバック関数を作ります

今て手元に100ポイントがあります。
りんご一つ買うと40ポイント減ります。
40ポイント以下になるとりんごが買えなくなり、エラーが表示されます。

コールバック関数.js
var asyncBuyApple = function(restPoint, callback){
  setTimeout(function(){
    if(restPoint >= 40){
      callback_pointCalculate(restPoint-40, null);
    }else{
      callback_pointCalculate(null, '金額が足りません。');
    }
  }, 1000);
}

コールバック関数を複数非同期処理

コールバック関数地獄.js
asyncBuyApple(100, function(restPoint, error){
  if(restPoint !== null){
    console.log('1回目の残りのポイントは' + restPoint + '円です。');
    asyncBuyApple(change, function(restPoint, error){
      if(restPoint !== null){
        console.log('2回目の残りのポイントは' + restPoint + '円です。');

        asyncBuyApple(change, function(restPoint, error){
          if(restPoint !== null){
            console.log('3回目の残りのポイントは' + restPoint + '円です。');
          }
          if(error !== null){
            console.log('3回目でエラーが発生しました:' + error);
          }
        });
      }
      if(error !== null){
        console.log('2回目でエラーが発生しました:' + error);
      }
    });
  }
  if(error !== null){
    console.log('1回目でエラーが発生しました:' + error);
  }
});

上記の例を見ますと、ネストが深く、これが仮に100回の処理がある場合、まさに大変なことになり、バグも見つかりにくなります。:cold_sweat:

コールバック関数地獄から抜け出そう:Promise

コールバック関数の問題を解決するために、Javascriptでは【Promise】という仕様が登場しました。:clap_tone1::clap_tone1:

※PromiseはES6対応ですので、ES5の場合はbluebird等のライブラリーが必要になります。

Promiseの関数を見てみましょう!

Promise.js
var promiseBuyApple = function(restPoint){
  return new Promise(function(resolve, reject){
    if(restPoint >= 40){
      resolve(restPoint-40);
   //実行成功、resolveをPromiseコンストラクタに渡す
   //return restPoint-40 と同じ意味です。
    }else{
      reject('ポイントが足りません。');
   //実行失敗の場合、rejectをPromiseコンストラクタに渡す
   //return 'ポイントが足りません。' と同じ意味です。
    }
  });
}

・Promise関数はPromiseオブジェクトを返します。
・成功の場合は「resolve」、失敗の場合は「reject」関数をPromiseコンストラクタに渡します。

Promise関数複数処理

Promiseではresolveやrejectをthenメソッドに渡します。

Promise_then.js
promiseBuyApple(100).then(function(restPoint){
  console.log('残りのポイントは' + restPoint + 'です');
  return promiseBuyApple(restPoint);
}).then(function(restPoint){
  console.log('残りのポイントは' + restPoint + 'です');
  return promiseBuyApple(restPoint);
}).then(function(restPoint){
  console.log('残りのポイントは' + restPoint + 'です');
}).catch(function(error){
  console.log('エラーが発生しました:' + error);
});

 ・Promiseを使うことで、コードが綺麗に整いました。
 ・最初の関数が実行した後、thenメソッドのコールバック中でreturnされた結果が次のthenメソッドのコールバックに引数として渡されます。
 ・then(function(restPoint)restPointに成功すればresolveが渡されて、失敗の場合はrejectが渡されます。
 ・エラーの場合はcatchメソッドが実行されます。

簡単に言うといかの感じになります。

以下の内容はこちらを引用。

コールバック関数地獄
A(function(){
  B(function(){
    C(function(){
      console.log('Done!');
    });
  });
});
Promiseを使用後
A().then(B).then(C).then(function(){
  console.log('Done!');
});

更に、async、awaitはPromiseを簡単に扱える仕組み

・内容は以下を引用しました。
Promiseが分かれば簡単!async, await
【JavaScript入門】5分で理解!async / awaitの使い方と非同期処理の書き方

Promiseだけでも同じ処理ができますが、async、awaitを使うとよりスッキリしたコードになります。

基本的な構文について

まずは、基本の構文を見てみましょう!
「async」は「function」の前に記述するだけで非同期処理を実行できる関数を定義できます。

async function() { }

このようにasyncを記述しておくと、この関数はPromiseを返すようになります。また、「await」はPromise処理の結果が返ってくるまで一時停止してくれる演算子となります。

await Promise処理
・ここで注意ですが、「await」は「async」で定義された関数の中でしか使えません。今では「await」と「async」は一緒に使われてることが多いですね!

実際の例を見てみましょう。
以下がPromiseの処理(非同期)です。

基本なPromise処理
function myPromise(num) {
  return new Promise(function(resolve) {

    setTimeout(function() { resolve(num * num) }, 3000)

  })
}

非同期処理で3秒間かかる処理を記述し、引数numで受け取った値を2乗した結果を返す単純な処理です。

以下は「then」を使わずに、「await/async」を利用します。

Promise処理でasyncを使用
async function myAsync() {

    const result = await myPromise(10);

    console.log(result);

}

myAsync();

この例では、asyncを付与することで非同期処理の関数を作成していますね。その関数内でPromise処理を記述している「myPromise()」の前に「await」を付与しているのが分かります。

これにより、3秒後に結果が返ってくるPromise処理を一時的に待つことになり、結果を取得した瞬間に関数内の処理が続行されるのです。実行結果には引数に与えた「10」が2乗された値「100」が取得できていますね。

「then」を使わずに非同期処理を複数実行する方法

Promise処理でthenを使用
myPromise(10).then(function(data) {

    console.log(data);
    return myPromise(100)

}).then(function(data) {

    console.log(data);
    return myPromise(1000)

}).then(function(data) {

    console.log(data);

})

同じ処理をasync、awaitで書くと

Promise処理でasyncを使用
async function myAsyncAll() {

    console.log(await myPromise(10));
    console.log(await myPromise(100));
    console.log(await myPromise(1000));

}

myAsyncAll();

「Promise.all」と「async/await」の並列処理

「async/await」を使い、Promise処理が終わり、resolve(reject)が返された後にまた次のPromise処理を実行するのもいいですが、例えばPromise処理がAPIでデータを取得する処理としよう、仮に取得するAPIが合計個あるとします、API処理で1分かかり、全てのAPIを取得するだけで20分かかります。:point_up:
これは非同期で一括取得したほうが速いですよね!

ここで「Promise.all」と「async/await」の並列処理を紹介します。

まずは「Promise.all」を使った一括処理

Promise.all([
    myPromise(10),
    myPromise(100),
    myPromise(1000)
]).then(function(data) {

    console.log(data);

})

上記を見てみますと、一括処理はできたが、個別の処理結果を見たい時は少し不便ですよね。

ここで「async/await」を使った一括処理

nc function myAsyncAll() {

    const r1 = myPromise(10);
    const r2 = myPromise(100);
    const r3 = myPromise(1000);

    console.log(await r1, await r2, await r3);

}

myAsyncAll();

上記を見ますと、Promise処理を全て起動させて変数に格納し、結果を取得できます。

おまけに、以下はSPAで一括API取得処理の例

一括処理
async function xxx() {
  let res1;
  let res2;
  let res3;
  try {
    [res1, res2, res3] = await Promise.all([
      axios.get('http://.../get1').catch(e => { throw 'get1 error '+e.message}),
      axios.get('http://.../get2').catch(e => { throw 'get2 error '+e.message}),
      axios.get('http://.../get3').catch(e => { throw 'get3 error '+e.message}),
    ]);
  } catch(err) {
    console.log(err);
    return; // 1つでもエラーになったら、関数を抜ける
  }

  // 3つ全てが正常データを取得できたとき、以下を実行
  console.log(res1);
  console.log(res2);
  console.log(res3);
}

まとめ

いかがでしょうか。
今回はJavascriptの同期/非同期、コールバック関数、Promise関数、Async/Await、非同期一括処理についての簡単な紹介をしました。
また今後も現場で活用していただければ嬉しいです!:relaxed:

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

Element UI (Vue Component Library) の導入

はじめに

フロント : Vue
バック : Laravel
で開発をしていた際に、楽にUI作れないかなーと思い探した結果見つけた

  • Element UI

を導入してみます。

インストール

公式ドキュメント
npm でインストールします。

npm i element-ui -S

npm installの-Sオプションについて
上記にもある通り、「-S」は必要ないかもしれないですが、私は公式通りに導入しました。

app.jsに追記

公式ドキュメントの通りに下記を追記

app.js
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

new Vue({
  el: '#app',
  render: h => h(App)
});

終わりに

上記手順が終われば、あとは公式ドキュメントにあるようなボタン、ラジオボタン、チェックボックスが使えるようになります。超便利で手軽!!

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

Vuexでstoreをモジュール分割しようとしたら参照先でundefined propertyっていわれた

モジュール構成は以下

# before

src/
|--store/
| |--index.js

# after

src/
|--store/
| |--index.js
| |--modules/
| | |--user.js

対処したのが以下

- this.$store.userInfo
- this.$store.dispatch('getUser')

+ this.$store.user.userInfo
+ this.$store.dispatch('user/getUser')

これで小一時間…

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