20200714のvue.jsに関する記事は17件です。

vue(Nuxt.js)で環境ごとにURLのリンク先を変える方法

vue(Nuxt.js)で環境ごとにURLのリンク先を変える方法です。

<template>
  <div>
    <button @click="toLink">リンク先へ</button>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  methods: {
    toLink() {
      let url = ''
      switch (window.location.hostname) {
        case 'https://dev.demo.com':
          url = 'https://dev.demo.jp'
          break
        case 'https://stg.demo.com':
          url = 'https://stg.demo.jp'
          break
        case 'https://demo.com':
          url = 'https://demo.jp'
          break
        default:
          url = 'https://localhost:3000'
          break
      }
      window.location.href = url
    }
  }
})
</script>

window.location.hostnameで現在ページのURLのホスト名を取得しています。
それをswitchして、環境ごとにリンク先のURLを変えています。

window.location.hrefでページ遷移させることが可能です。

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

Vuexの名前空間を使ったactionsをJestでMockする

はじめに

公式に名前空間を使わないactionsをMockする方法は記載されていますが、名前空間を使ったactionsのMock方法が見当たらなかったので、試してみてできた方法をここに記載します。

やり方

対象のコンポーネント

こんなmethodsを持っているコンポーネントを想定します。

  methods: {
    ...mapActions('namespaceA', ['hoge']),
    ...mapActions('namespaceB', ['fuga']),
}

Mock

こんな感じでMockできます。

const localVue = createLocalVue()
localVue.use(Vuex)
const actions = {
  'namespaceA/hoge': jest.fn(),
  'namespaceB/fuga': jest.fn()
}

const wrapper = shallowMount(Component, {
    store: new Vuex.Store({
      actions,
      mutations: {},
      state: {},
    }),
    localVue
})

テスト

こんな感じでテストできます。

expect(actions['namespaceA/hoge']).toHaveBeenCalled()
expect(actions['namespaceB/fuga']).toHaveBeenCalled()

もしかしたら、もっとスマートな方法があるかもしれませんが、こういう方法もあるということで。。

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

【Nuxt.js】Nuxt文法編:mixin

mixinとは

? この記事はWP専用です
https://wp.me/pc9NHC-s6

再利用可能な部品たちを
まとめて書いて使いまわせるもの✨
変更したい時はmixinだけ変更すればOK?‍♀️
管理がとっても便利になります!

実際に例を見ていきましょう?

簡単な使い方( js )

jsファイルを使いまわしてみます?

グローバルで使用することはないので
ローカルでご紹介??

ローカルで使用

スクリーンショット 2020-07-13 14.30.12.png

ただconsoleを出すだけのシンプルなもの

file
mixins/
--| mixin.js
pages/
--| index.vue

【mixin.js】
mixinsフォルダを作成し
その中にmixin.jsを作成

mixin.js
export default {
 created () {
   this.hello()
 },
 methods: {
   hello () {
     console.log('hello from mixin!')
   }
 },
}

【index.vue】
mixinをimportするだけ

index.vue
<template>
 <div class="page">
 </div>
</template>

<script>
import Mixin from '../mixin/mixin.js'

export default {
 mixins: [ Mixin ],
}
</script>

コンフリクトが起きた場合はマージされる

? 続きはWPでご覧ください?
https://wp.me/pc9NHC-s6

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

Laravelとかインストール

本番環境ではnode.jsを利用せず、Laravel7とVue.js使いたかった開発環境メモ。

Composerのインストール

  1. Composer-Setup.exeをダウンロードしてインストールする。
    Developer modeはチェックしない。
  2. 環境変数PATHにC:\Users\ユーザー名\AppData\Roaming\Composer\vendor\binを追加する。

Laravelインストーラーのダウンロード

composer global require laravel/installer

ひたすら待つ。
WindowsではC:\Users\ユーザー名\AppData\Roaming\Composer\vendor\laravel\installer
にダウンロードされる。

Laravelプロジェクトの作成

否応なく最新Laravelでプロジェクトを作る時は、下記のどちらか。
ひたすら待つ。

laravel new SampleProject
composer create-project --prefer-dist SampleProject

Laravelのバージョンを指定したプロジェクトを作る時。(下記は7系の最新)
予め求めているバージョンを決定している時は、バージョンを細かく指定すればいい。
バージョンは、Composer - laravel/laravelで管理されているバージョンが指定できる。

v7の最新バージョンで作りたい場合

composer create-project --prefer-dist "laravel/laravel=7.*" SampleProject

v6.12.0で作りたい場合

composer create-project --prefer-dist "laravel/laravel=6.12.0" SampleProject

--prefer-dist は、zipでダウンロードしてくるオプションなので、指定した方が早くダウンロードしてセットアップが終わるらしい。

Laravelバージョン確認

cd SampleProject
php artisan -V

で表示されるバージョンは、laravel/laravelのものではなくて、laravel/frameworkのもの。

Laravel起動を試す

cd SampleProject
php artisan serve

んで出てきたURLにアクセスすると動く。
Ctrl+Cで終了させる。

node.jsインストール

node.jsから推奨版をダウンロードしてインストールする。
次へ次へでいい。

モジュールのインストール

cd SampleProject
npm install

SampleProject/node_modules が作られる。
なんか警告でまくるけどよくわからんので放置。

vue.jsのインストール

cd SampleProject
npm install vue

コンポーネントの作成

SampleProject/resources/js/HeaderComponent.vue を作る。

HeaderComponent.vue
<template>
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-8">
        <h1>This is header!</h1>
      </div>
    </div>
  </div>
</template>

Viewの作成

SampleProject/resources/views/welcome.blade.php を作る。

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Laravel</title>
    <!-- laravelmix style -->
    <meta name="csrf-token" content="{{ csrf_token() }}"> 
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">
    <link rel="stylesheet" href="{{ mix('css/welcome.css') }}">
    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div id="app">
     <header-component></header-component>
   </div>
    <!-- laravelmix-style -->
    <script src="{{ mix('js/app.js') }}"></script>
  </body>
</html>

app.jsの修正

SampleProject/resources/js/app.js を修正する。
HeaderComponent.vue を認識させる。

app.js
require('./bootstrap');

window.Vue = require('vue');

Vue.component('header-component', require('../components/HeaderComponent.vue').default);

const app = new Vue({
    el: '#app'
});

cssの追加

SampleProject/resources/sass/welcome.scss を作成する。

welcome.scss
.container {
  h1 {
    color: red;
  }
}

webpack.mix.jsの修正

SampleProject/webpack.mix.js を修正する。
作成したwelcome.scss をcssとして利用できるようにする。

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

mix.sass('resources/sass/welcome.scss', 'public/css');

npmでコンパイル

cd SampleProject
npm run dev

SampleProject/public 配下に、jsやcssが出来上がる。

prodで実施するとjsやcssがminimizeされるのとvue.jsのライセンスファイルが作られる。

npm run prod

実行

cd SampleProject
php artisan serve

vueが処理しきる前に一瞬表示されるのを防ぐ

v-cloak を利用すると防げる。

<div id="app" v-cloak>
[v-cloak] {
  display: none;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue】Vue3でScopedCSSが改善されるという話

更新内容

https://github.com/vuejs/rfcs/pull/119

ScopedCSSの改善

以下のissueで議論されている下記の問題がこの更新で改善されます。
https://github.com/vuejs/vue/issues/11245#issuecomment-604150460

scoped によって、親コンポーネントのスタイルは子コンポーネントに漏れません。ただし、子コンポーネントのルートノードは親スコープの CSS と子スコープの CSS と両方によって影響を受けます。これは、設計上、親はレイアウトが目的で子のルート要素をスタイルすることができます。
https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html

v-slot, ::v-deep, scopedのスタイリング記述方法の改善

ScopedCSSの記述方法が改善されます。
ディープセレクタの記述方法は従来,以下の記述でしたが,

style2.vue
<style>
.a ::v-deep b ...
.a >>> b ...
.a /deep/ b ...
</style>
or
<style scoped>
.a ::v-deep b ...
.a >>> b ...
.a /deep/ b ...
</style>

以下のような記述ができて、v-slot, ::v-deep, scopedの記述がより直感的にスタイリングできるようになるみたいです。

style3.vue
<style> <!-- global -->
/* deep selectors */
.a ::v-deep(.b) ...

/* slot */
.a ::v-slotted(.b) ...

/* global */
.a ::v-global(.b) ...
</style>

<style scoped> <!-- scoped -->
</style>

<style deep> <!-- ::v-deep -->
</style>

<style slotted> <!-- ::v-slotted -->
</style>

おわりに

何か間違えや質問などあればコメントお願いします。

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

VueJS でYubinbangoライブラリを使えるようにする改修

概要

郵便番号で都道府県情報検索して住所自動入力する機能があれば便利だとおもいます。インターネットでそんなライブラリがあるか検索してみると下記のJSライブラリ見つけました。

導入方法はすごく簡単で手順書によっては下記のようにフォームをおけばOKです。

    <form class="h-adr">
      <span class="p-country-name" style="display:none;">Japan</span><input type="text" class="p-postal-code" size="3" maxlength="3">
      <input type="text" class="p-postal-code" size="4" maxlength="4"><br>

      <input type="text" class="p-region" readonly /><br>
      <input type="text" class="p-locality" readonly /><br>
      <input type="text" class="p-street-address" /><br>
      <input type="text" class="p-extended-address" />
    </form>

もちろんJSライブラリのインポートもしなければならないです。

    <script src="https://yubinbango.github.io/yubinbango/yubinbango.js" charset="UTF-8"></script>

ただ開発しているシステムのフロントはVueJSで実装していることで通常JSライブラリを使えるようにNPMでライブラリ導入してapp.jsでrequiredしましたが下記のような問題が発生しました。

  • 郵便番号入力したら住所情報自動検索はできましたが他の入力欄でキー叩いたら住所欄の内容は空白になってしまいました。

原因の調査

いろいろ調査してみたらやっと原因がわかりました。VUEJSは通常のDOM使わずに自分のDOMでUI要素のみなを管理しているということが忘れてしまいました。そういうことで問題発生のながれは下記のようです

  • YubinbangoはJSライブラリだからJQUERYでHTMLのDOMつかって都道府県の情報を検索完了したあと、住所欄探して検索結果自動的に入れてくれる。
  • VUESJはHTMLのDOM使わないことで行った住所欄の更新について分かりません。
  • VUEJSは次の更新操作で住所らんの値を自分持っている値(NULLかも)で入れてしまって空白となる。

改修

使えなくて残念の気持ちしながらもう一回解決方法探してみると「Yubinbango-Core」とういう物見つけましていい記事も見つけました。

https://qiita.com/kiyc/items/752f5a167c975582ebc2

教えたくれた通りにしてみたら想像外に[YubinBangoCore.core is not a constructor]とか「TypeError: Cannot read property 'Core' of undefined"」というJSエラーが出てきました。

YubinbangoのGithubでみなからのFeedbackみてみると既存の問題のようです。

しょうがないだからYubinbangoExportさせるようにNodeModuleのJSファイルを直接修正することにしました。

スクリーンショット 2020-07-14 11.33.00.png

app.js
window.YubinBango = require('yubinbango-core')

HelloWorld.vue
<template>
  <div class="hello">
    <input v-model="zip"/>
  </div>
</template>

<script>
  export default {
    name: 'HelloWorld',
    props: {
      msg: String
    },
    data: function(){
      return {
        zip: null,
        address :null
      }
    },
    watch: {
      zip: function(zip) {
        let _this = this;
        new window.YubinBango.Core(zip, function(addr) {
          console.log(addr);
          _this.pref_id  = addr.region_id // 都道府県ID
          _this.locality = addr.locality  // 市区町村
          _this.street   = addr.street// 町域
        })
      }
    }


  }
</script>

あまりよくない方法ですが暫定的な策としてつかっても良さそうです。もちろんnpm更新で修正したコードがなくなる可能性があることでお気をつけてください。

以上です。

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

【vue】 親コンポーネントのstyleタグから、子コンポーネントのidやclassの情報を変更できるようにするための方法メモ

はじめに

vueで、親コンポーネントのstyleタグから、子コンポーネントのidやclassの情報を変更できるようにするための方法。
自分用メモ。

内容

下記の方法

::v-deepを子コンポーネント内部の変更させたいidやclassの前に記述する

を行うことで子コンポーネント内部の要素も変更されるようになる。

具体的な記述は以下。

親コンポーネント
<template>
    <div class="parent">
        <p class="text">親コンポーネントpタグ</p>
        <Child />
    </div>
</template>

<script>
import Childfrom '../components/Child.vue'
export default {
    name: 'Parent',
    components: {
       Child
    }
}
</script>

<style lang="scss" scoped>
::v-deep .text {
  color: red;
}
</style>
子コンポーネント
<template>
 <div class="children">
  <p class="text">子コンポーネントpタグ</p>
 </div>
</template>

<script>
 export default {
  name: 'Child'
 }
</script>

以下の記事を参考させていただきました。ありがとうございます。

https://designsupply-web.com/knowledgeside/4833/

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

Webサーバーの立ち上げからアプリケーションの作成まで全て一人でやってみた件

初めに

 今まで書籍でLaravelについて勉強したり、Laravelの仕組み(バインドについてなど)を調べて記事を書くことなどをしてきたのですが、最近それらが飽きてきてしまったのでLaravelを使用したWebアプリケーションをAWSのツールを用いて作成してみました。そして、このアプリを作成した経験を記事にすれば自分と同じような境遇の人の助けとなったり、このアプリケーションの宣伝になるかもと思ったので、このアプリケーションの作成やAWSのツールを使用した際に個人的に苦労したこと・気を付けたことをここへ書いてみました。
 この記事は大きく分けて四章あるのですが、章ごとの内容は独立しているので気になるところを好きなように読んでください。

Webアプリ宣伝編

 今回私が作成したWebアプリケーションはデンデンデン・・・・バーン!!
ロッテンポテト」です!(トマト?何のことですか?)
このアプリは映画レビューサイトです。もっと詳しく言うと、管理する人(僕です)が最近見た映画を紹介するので、それに対しレビュワーたちが気ままにレビューをする感じです。
 このサイトのトップページはこんな感じです。
ロッテンポテト トップ.png
ほかのページはこんな感じです。
ロッテンポテト 映画一覧.png

 画像を見てみると新規登録とか、満足度とかありますが気になる方はトップページを見てみて下さい。また、このWebアプリに関する疑問やこんな映画をみんなとレビューしてみたいな、などの要望がありましたら、このアプリ用のtwitterアカウントへDMを送ってください!
twitterアカウントはこちら

AWS編

※インフラ、ネットワーク、Webサーバーに関する知識が全くない中で自分なりに調べてこの章を作成しました。なので間違いがあるかもしれません。もし間違い等がありましたら、指摘していただけるとありがたいです。

 今回自分が使用したAWSのツールの関係を図にするとこんな感じです。
AWS.png

 この図に書いてある丸付きの番号は一般ユーザーがWebサーバー(今回はEC2)へリクエストを送るまでの道順を表しています。この番号通りにそれぞれのツールのやっていることを説明すると、

  1. 一般ユーザーがブラウザなどからドメインを通してWebサーバーへアクセスする際まずはユーザーからAWSのDNSサーバーであるRoute53へ、ドメインに紐づいたWebサーバーのグローバルIPアドレスを教えるようにという命令が出される。そしてRoute53はElastic IPで管理しているWebサーバーのグローバルIPアドレスをユーザーへ教える。
  2. グローバルIPアドレスを取得したユーザーはVPC(ネットワーク空間のこと。ここにWebアプリを構成するツールを置く。)の入り口であるインターネットゲートウェイを通る。
  3. インターネットゲートウェイからロードバランサーまではhttps通信(http通信より安全に通信が行える通信)でリクエストの内容が伝えられ、そのリクエストはルートテーブル(VPCの外からリクエストが来た際の宛先を設定する)で設定されたサブネット内のEC2へ送られる。
  4. ロードバランサーから送られたリクエストはセキュリティグループにてEC2へ通すか否かの判断が下され、許可が出ればそのリクエストはEC2へ行きその結果がWebアプリへ反映される。

補足事項

  • グローバルIPアドレスとは?
    AWSでサーバーを作成するにあたり二つのIPアドレスが使用されます。一つがグローバルIPアドレスでもう一つがプライベートIPアドレスです。グローバルIPアドレスはElastic Ipなどで後から割り当てる、VPC外からみたサーバーのアドレスを示すもので、プライベートIPアドレスはサーバーの作成時に自動的に割り当てられる、VPC内からみたサーバーのアドレスです。もしVPC内のみ(ローカルの環境)で通信を行う際はプライベートIPアドレスのみで大丈夫です。しかしVPCの外から通信を送る場合(例:第三者が利用者となるWebアプリケーションを運用する場合)はグローバルIPアドレスがなくてはサーバーへアクセスできません。

  • Certificate Manager とは
    ユーザーに対し、このWebアプリはhttps通信(SSL通信)を行っていることを証明する働きをしています。この証明をしているWebアプリはブラウザで見る際にURLの左側に鍵マークがあります。このマークがないWebアプリはユーザーのデータが漏洩する可能性が高いので、注意してください。

参考にした記事
AWS初心者 入門編 脱・知ってるつもり!AWSのネットワーク関連用語を基礎からおさらい
ウィキペディア HTTPS
AWS ルートテーブル

 自分が使用したAWSのツールの概要は以上です。今度は導入の際に自分が行ったことや参考にした記事をツールごとに紹介していきます。

AWSのツールを使う前に

 AWSアカウントを作成する際の注意点やAWSの料金管理の仕方は以下の記事から教わりました。AWSを初めて使うけどどうすれば良いかよくわからないという方はこの記事を参考にしてみてください。
Qita AWSアカウントを取得したら速攻でやっておくべき初期設定まとめ

VPC&EC2&RDS

 AWSでのVPCの立ち上げからEC2、RDSの作成は以下の記事を参考にしました。各章ごとの内容がわかりやすく書いてありますので、自分の知りたいことをこの記事から探すような活用の仕方が良いと思います。
(下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで

route53

 ドメインの作成からドメインとグローバルIPアドレスの結びつけをroute53で行いました。
参考にした記事は以下の二つです。
Route 53 でドメインを取得・購入する(2019版
AWS Amazon Route 53 の開始方法

https通信(SSL通信)

 EC2を作成し、Elastic IPでグローバルIPアドレスを設定しただけだと、http通信でユーザーとサーバーの通信が行われるため安全な通信とは言えません。(通信に関する知識が全くないため、どこが危険なのかはわかりません。)そこでhttp通信をhttps通信に切り替える必要があります。
 自分がhttp通信をより安全なhttps通信に切り替える時やhttps通信(SSL通信)を行っていることに対する証明書を発行する時に参考にした記事はこちらです。
ナレコムAWSレシピ AWSでWebサイトをHTTPS化 その1:ELB(+ACM発行証明書)→EC2編

Webサーバーソフトウェア編

 自分のOS、Apacheのバージョンはこちらです。

ツール バージョン
Ubuntu 18.04.4 LTS
Apache 2.4.29

 LAMPの導入などはいろんな方が記事を書いてくれているので、それぞれの環境に合うものを参考にしていただければと思います。この章では自分が今までWebアプリケーションをデプロイした経験がないゆえにはまったことがあったので、それを紹介します。
 ちなみに自分がLAMPを導入する際に参考にした記事はこちらです。
Install PHP 7.4 on Ubuntu 18.04

Apacheではまったこと

 自分がはまったことは、ブラウザでドメインを入力したときに自動的に自分のプロジェクト/public/index.phpを表示するようにApacheを設定するにはどうすれば良いのかということです。自分が見つけたこの問題に対する解決策は、Apacheの設定ファイル(/etc/apache2/apache.confなど)内のhttp通信(port80を使用)のときに表示するファイルのパスを設定する部分(<VirtualHost *:80>から</VirtualHost>にかけて)にDocmentRoot /var/www/html/自分のプロジェクト/public/を加えるというものでした。しかし自分の環境の場合それだけではうまくいきませんでした。なぜなら、自分のようにUbuntuをOSとしている場合のApacheの設定ファイルは一つにまとまっているわけではなく、いくつかの設定ファイルに分裂していたからです。
 ではDocmentRoot ~をどこへ加えたのかというと、/etc/apache2/sites-available/000-default.confに加えることでうまくいきました。
(自分のWebアプリケーションの通信はインターネットゲートウェイからロードバランサーまではhttps通信ですが、EC2からロードバランサーまではhttp通信のためhttp通信の設定を行う/etc/apache2/sites-available/000-default.confを書き換えました。もしEC2からロードバランサーまでをhttps通信で行う場合はおそらくhttps通信の設定を行う/etc/apache2/sites-available/default-ssl.confを書き換える必要があるかと思います。)

この問題に対する解決策は下の記事を参考にさせていただきました。
index意外のページにアクセスすると404エラーが発生する

アプリケーション編

 このWebアプリケーションに使用した各ツールのバージョンは以下の通りです。

ツール バージョン
php 7.4
Laravel 7.12.0
Vue 2.6.11

Laravel(バックエンドorサーバーサイド)

Laravelのインストール時にはまったこと

 メモリの小さいEC2を使用したがゆえにLaravelの一部しかインストールされないという問題にはまり、そのとき自分がteratailで質問したときに得た回答と参考にした記事は以下の通りです。間違えてメモリを1GBにしてしまった時などにはぜひ参考にしてみて下さい。

AWSのEC2上でのLaravelとAWSでのRDS(MySQL)の環境で"php artisan migrate"を実行した時のエラー
Life with IT swap領域拡張手順(ファイル割当)

コードを書く上で気を付けたこと

 Laravelを使用しコードを書く上で気を付けたことは3つです。

  1. 設計パターンにMVC(Model View Controller)を用いる
  2. MVCのうちのControllerの内容はなるべく分かり易いものにする
  3. phpとRDBとの手続きやOAut認証の手続きはModel内に収める

 1の理由はADR(Action Domain Response)など設計パターンには様々なものがありますが、初めてFWに触れる自分にとって単純なものを選ぶ方がやりやすいと思ったからです。
 2にある「分かり易い」の基準は二つあります。一つ目はController内のメソッドの引数と返り値には必ず型の指定を行う、二つ目はController内のすべてのコードの質を一定の状態に保つというものです。二つ目のコードの質を判断するために自分はPHPStanという静的解析ツールを使用しました。このツールはレベル別にコードの間違いを指摘してくれます。レベルの一番低いものだと、コード内に宣言されていない変数やメソッドが使用されていないかを確認してくれ、レベルが上がるにつれてメソッドの引数の型が指定されているかや返り値の型の指定がされているかなどを確認してくれます。コードの質のチェックだけではなく、コードのデバックにも使用できて便利です。
 2,3を気を付けるようになった理由は自分が他の方が以前書いたコードの修正を行った時の経験から来ています。私が修正依頼を受けたコードはGoogleAppScript(JavaScriptにGoogleカレンダーなどのGoogleのツールと簡単に連携が取れるライブラリが付け加えられた言語)で書かれたものでした。GASにはTypeScriptのような型の指定をする機能はありませんし、修正を行うコード自体にLaravelにおけるpublic/index.phpのような処理の全体が分かり易く書かれたコードはありませんでした。そのため個々のメソッドの役割や処理全体の把握にとても時間がかかりました。今回のWebアプリケーションは自分単独で開発・運用するもので自分以外の人が関わることはありませんが、未来の自分は他人と同じような理解力しかないので、そんな自分でもすんなり理解できるにはどうすれば良いのか考えた結果、今回のWebアプリケーションのコードを書く際も2,3を気を付けるようにしました。

機能を実装する上で気を付けたこと

 機能を作成する際に気を付けたことは小さく作り、小さく試し、小さく実装するということです。例えばこのような要件の機能を付けることになったとします。
ユーザの入力事項を指定のデータベースへ登録する。
この機能を作成するには以下の手順で作成するとします。

  1. 登録するデータベースの作成
  2. 入力値をデータベースへ登録する機能の作成(Model)
  3. 入力値をModelへ伝え、Modelの結果によって動作を変える機能の作成(Controller)
  4. 入力値のバリデーションの作成
  5. 入力ホームの作成
  6. フォームとデータベースの登録の機能を結びつけるためのルーティング

 この機能が正常に作成・実装できたかどうかを判断する方法の一つとして、これらの機能を一気に作成・実装し、Laravelのもとからあるデバック機能を使用してエラーの有無をブラウザ上で確認する方法があります。この方法はスピーディーに実装できる反面、本番用のデータベースへ値を入れなくてはならなかったり、複数のパターンで複数回テストするのに手間がかかったりします。そこで自分が行った方法は、手順を一つ進めるごとにその手順で行ったことが要件を満たすものかテストを行うという方法です。例えば、1が完了したらLaravelのテスト機能を使用して要件に合致するレコードが作成できたのか確認し、2が完了したら作成した機能にテスト機能を使用して入力値を入れることで指定のレコードへ登録できたかを確認するという感じです。この方法は、一つ一つ手順を進めるごとにテストを作成しなくてはいけないので実装のスピードは遅くなる反面、Laravelのテスト機能のおかげで本番のデータベースへ値を入れる必要がなかったり、factory()などのヘルパ関数を使用して様々なパターンで100件単位のテストを一瞬で行えたり、個別にテストを行うことによりエラーの原因を絞って考える(例えば、もし手順3の段階でエラーが出た場合、2までは正常だったため原因は手順3で行ったことにあると違いないと推測できる)ことができます。
 Laravelのテスト機能をはじめから使用するのは大変かもしれませんが、Laravelの公式ドキュメントでもたくさんのテスト機能の紹介がされているので、Laravelを使用するのならばぜひ使ってみて下さい。

Vue(フロントエンド)

LaravelとVueの両方で開発経験がなくてLaravelでアプリケーションを開発する方へ

 これは自分の質問に答えてくれたエンジニアの方が言ってくれたことであり、自分もLaravelとVueを組み合わせて開発していて思ったことなのですが、もしLaravelとVueのどちらも今まで触ったことがない場合はLaravelのみでWebアプリケーション開発を行う方が良いということです。なぜならWebアプリケーション開発で二つのFWを組み合わせて使用しようと思うと、考えることがFWが一つのときの倍ぐらいに増えてデプロイまでが長くなってしまうからです。デプロイまでが長くなると気力が一気に落ちると思うので、最初のうちはなるべく単純なものの方が良いかなと思います。

LaravelにおけるVueの実装

LaravelでのVueの実装は以下の記事を参考にしました。
Laravel7からVue.jsを使う最短レシピ

自分がドはまりしたところ

 自分がLaravelとVueの組み合わせたときに一番悩んだのはVueのコンポーネントにフォームを作成した際、そのフォームの値をどうやってCSRF(ユーザーになりすますことで他のサイトから不正にリクエストを送ること)対策をしたうえでバックエンドへ伝えるかということです。LaravelのViewの役割をもつblade.phpでのLaravel7に対するCSRF対策はこんな感じです。

//省略
<form action="バックエンドまでのパス" method="post">
@csrf
<input name="name" type="text">
</form>

 これをVueのコンポーネントのフォームでも同じようなことをしようとすると@csrfの部分が無効となり419エラーで怒られてしまいます。この問題は、コンポーネントにCSRF対策を書くのではなく、コンポーネントを表示しているblade.phpにjQueryでこのように付け加えることで解決できます。

$('body').on('submit', 'form', function () {
$(this).append('@csrf')
});

 このコードで書いてあることは、body要素の中のform要素にsubmitというイベント(<input type="submit">を実行する)が発生した時にform要素に@csrfを加えるということです。解決方法は他にもいろいろあると思います。この解決方法は自分がteratailで質問した際に教えて頂きました。その時の質問と回答はこちらです。
Laravelを使用したVueのcomponent内のformのpostリクエストで419エラー

 LaravelとVueにおけるこの他のCSRF対策を紹介した記事はたくさんありました。また、Laravelの公式ドキュメントではCSRF対策をしているミドルウェアを無効にする方法が紹介されていました。しかし、CSRF対策が書かれた記事に書いてある内容が自分にとって複雑に感じるものが多かったり、CSRF対策を無効にしてWebアプリケーションの安全性を下げるのは良くないと思いjQueryを使用した方法を選びました。

終わりに

 Webアプリケーションを作成しただけではなく、それらを運用する環境まで整えたのでたくさんの時間(3か月くらい)がかかりました。Webアプリケーションを作成しようと思わなかったら感じる必要のないストレスを感じました。しかしこの経験を通し、自分の頭の中でふわふわ浮いていたネットや書籍で知った言葉たちが、ようやく実感のある言葉になったなーという感覚を持てるようになりました。
 このWebアプリケーションのデプロイまでに自分がAWSに対して払った料金はドメイン取得時の千円ぐらいです。またEC2で初めに入れたOSが気に食わなければ何回も無料で作り直せます。(現に自分はAmazon Linux ⇒ Ubuntuへ変更しました。)AWSのEC2などのサービスは初めの12年は無料で使用できるので、初めてのWebアプリケーションのデプロイは年間で料金を払うようなレンタルサーバーよりもAWSを使用した方が良いと個人的に思っています。(BillingなどでAWSのコスト管理はしっかり行ってください。)
 なにも知らなかった自分がWebアプリケーションを作成できるようになったのは、無償でteratail・コミュニティなどで自分の質問を答えていただいた方々や分かり易いLaravelの公式ドキュメントを書いてくれた方々、書籍(PHPフレームワーク Laravel Webアプリケーション開発)に携わった方々、ネットで分かり易い記事を書いてくれた方々、お金がない日本人学生でもAWSを使いやすいようにしてくれた方々のおかげです。今後自分と同じような部分で悩んでいる人へ解決策を伝えたり、OSSへの貢献(できるかなー?)するなどで恩返しできれば良いなと思います。

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

Vue.jsの環境構築まとめ

Vue.jsというJavaScriptフレームワークを勉強しようと環境構築にちょっと時間がかかってしまったのでフロートしてのこしておきます[Windows]

Vue.jsにちょっと触れてみる

簡単なVue.jsを作成して雰囲気をつかんでみる

CDNで読み込むだけなので簡単に確認できる

<script src="https://unpkg.com/vue"></script>

</head>タグのすぐ上に挿入する

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue.jsサンプル</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <h1>Vue.js</h1>
  <div id="app">
    {{ message }}
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue'
      }
    });
  </script>
</body>
</html>

Hello表示を確認するのに一般的なコードですね

{{ message }}の部分が Hello Vue になって表示されます

なるほどつかいやすそうな気がする

ということで導入していきます

プログラミングの世界には便利なものはまとめて管理しようとする流れがあります

【Vue.js】も【npm】とうパッケージ管理ツールで利用できます

【npm】は【Node.js】というプログラグに組み込まれています

  • 【Node.js】の中の【npm】をつかって【Vue.js】を管理する流れです

まずはNode.jsをダウンロード、インストールしましょう

Node.jsのダウンロード

インストールしたらコマンドプロンプトから【Vue CLI】とインストールしましょう

ディレクトリを移動して下記を入力

npm install -g @vue/cli

ちょっと時間かかります

次に【cli-service-global】ファイルも必要になるのでインストール

npm install -g @vue/cli-service-global

これでVue CLIを使用できます
Vue.jsのコマンドツールなので後々役立つので入れていきましょう

まとめ

構築は比較的簡単な方だったとおもいますがディレクトリの移動や、コマンドを忘れてしまったりと細かいところでつまづきやすいです

メモとして残っていると安心です

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

vue-good-tableの検索ボックスに前回の検索キーワードを入れる

vue-good-tableの検索ボックスに、ローカルストレージなどに保存しておいた前回の検索キーワードを入れておく方法です。

環境

  • Vue.js 2.6.11
  • vue-good-table 2.16.3

HTML

vue-good-tableタグ内のrefで任意の名前を与えます。

<vue-good-table
  ref="my-table"
  :columns="columns"
  :rows="rows"
  :search-options="{
    enabled: true
  }">
</vue-good-table>

Vue.js

mountedで先ほど名前を与えたコンポーネントを取得し、そのglobalSearchTermにローカルストレージなどから取得した前回の検索キーワードを渡します。ここでは「my initial value」を代入しています。

// in js
mounted() {
  this.$refs["my-table"].globalSearchTerm = "my initial value";
}

サンプル

See the Pen vue-good-table initial global search by Kamiyama (@MtDeity) on CodePen.

参考

Global Search reset · Issue #452 · xaksis/vue-good-table

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

作成中の静的ファイルをターミナルからChromeですぐに確認する

何を書いた記事か

HTMLやJavaScriptのファイルを作成していて、それをブラウザ(Chrome)で確認したいとき、ターミナルから一発で確認する方法です。

Vueの勉強をしていて、新規に作成したファイルをわざわざChromeで開くのにFinder操作とかいろいろするのが面倒だったのでターミナルからワンライナーで開けるようにしました。

※MacOSでの操作方法を記載します。

こうなります。
open_in_chrome.gif

どうやるか

そもそも、ターミナルで指定ファイルをChromeで開くのは下記コマンドで実行可能です。

open -a '/Applications/Google Chrome.app' path/to/file

ただ、これをいちいち打っていくのは非常に面倒なので、 ~/.zshrc~/.bashrc などにaliasを定義しておきます。

alias chrome="open -a '/Applications/Google Chrome.app'"

これで、 chrome と打って対象のファイルを指定するだけで、そのファイルをChromeで開くことができるようになります。

chrome path/to/file

まとめ

ちょっとでも楽になる操作はどんどんaliasに突っ込んで行きましょう

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

ASP.Net Core+RazorPage+Vue(サンプルソース)

目的

 今まで書いてきた記事で作成していたASP.Net Core RazorPageでnon-SPAなVueコンポーネントの作成と、関連して作っていたTestCafeのテストコードをまとめたプロジェクトソースがある程度整ったのでサンプルs-すとして提供します。気が向いたら遊んでみてください。

前提

 ASP.NetCore RazorPage+Vue+blumaの環境を利用します。
 以前に書いた「Vue.jsを利用してみる(1)」と「Vue.jsを利用してみる(1)」を参照しての環境を構築します。

ソース

GitHUBの以下のURLに公開しています。
https://github.com/nosa67/RazorPageVue

提供内容

Vueコンポーネント

コンポーネント名 概要
vueCheckButton 複数選択可能なチェックボタン
vueRadioButton 未選択可能なラジオボタン
vueTextInput テキスト入力
vueIntegerInput 整数入力
vueRealInput 実数入力
vueTimeInput 時刻入力(サーバーではTimeSpan)
vueDateInput 日付入力(サーバーではDateTime)

バリデーション属性

バリデーション属性 概要
Required 入力必須
StringLength テキストの、最小長、最大長
Range 整数、実数、時刻の最小、最大、ステップ
Email メールアドレスかどうか
Url URLかどうか
Compare 2つのテキストの同一性

TestCafe

テストファイル 概要
VueCheckButton.test.ts チェックボタンのテスト
VueRadioButton.test.ts ラジオボタンのテスト
VueTextInput.test.ts テキスト入力のテスト
VueIntegerInput.test.ts 整数入力のテスト
VueRealInput.test.ts 実数入力のテスト
VueTimeInput.test.ts 時刻入力のテスト
VueDateInput.test.ts 日付入力のテスト

補足

 不要なコードを整理したり、バグを修正したりしていますので、今まで書いてきた記事のコードとは少し異なります。記事の方は修正しませんので、ソースを追ってください。テストコードがあるように、ある程度のテストはしていますが、まだまだバグはありますので使おうと思っているならもっとテストしてください。
 もともとの記事では、EdgeとIE11を別のコンポーネントにしていましたが、Edgeがchromiumベースになって、インターフェースがこなれたので、IE11のみ別コンポーネントになるように変更しています。
 ブラウザごとにインタフェースが異なるのを避けるなら、全て独自コンポーネントにしてもいいかもしれません。

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

ASP.Net Core+RazorPage+Vue(Non-SPA、サンプルソース)

目的

 今まで書いてきた記事で作成していたASP.Net Core RazorPageでnon-SPAなVueコンポーネントの作成と、関連して作っていたTestCafeのテストコードをまとめたプロジェクトソースがある程度整ったのでサンプルs-すとして提供します。気が向いたら遊んでみてください。

前提

 ASP.NetCore RazorPage+Vue+blumaの環境を利用します。
 以前に書いた「Vue.jsを利用してみる(1)」と「Vue.jsを利用してみる(1)」を参照しての環境を構築します。

ソース

GitHUBの以下のURLに公開しています。
https://github.com/nosa67/RazorPageVue

提供内容

Vueコンポーネント

コンポーネント名 概要
vueCheckButton 複数選択可能なチェックボタン
vueRadioButton 未選択可能なラジオボタン
vueTextInput テキスト入力
vueIntegerInput 整数入力
vueRealInput 実数入力
vueTimeInput 時刻入力(サーバーではTimeSpan)
vueDateInput 日付入力(サーバーではDateTime)

バリデーション属性

バリデーション属性 概要
Required 入力必須
StringLength テキストの、最小長、最大長
Range 整数、実数、時刻の最小、最大、ステップ
Email メールアドレスかどうか
Url URLかどうか
Compare 2つのテキストの同一性

TestCafe

テストファイル 概要
VueCheckButton.test.ts チェックボタンのテスト
VueRadioButton.test.ts ラジオボタンのテスト
VueTextInput.test.ts テキスト入力のテスト
VueIntegerInput.test.ts 整数入力のテスト
VueRealInput.test.ts 実数入力のテスト
VueTimeInput.test.ts 時刻入力のテスト
VueDateInput.test.ts 日付入力のテスト

補足

 不要なコードを整理したり、バグを修正したりしていますので、今まで書いてきた記事のコードとは少し異なります。記事の方は修正しませんので、ソースを追ってください。テストコードがあるように、ある程度のテストはしていますが、まだまだバグはありますので使おうと思っているならもっとテストしてください。
 もともとの記事では、EdgeとIE11を別のコンポーネントにしていましたが、Edgeがchromiumベースになって、インターフェースがこなれたので、IE11のみ別コンポーネントになるように変更しています。
 ブラウザごとにインタフェースが異なるのを避けるなら、全て独自コンポーネントにしてもいいかもしれません。

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

ASP.Net Core+RazorPage+Non-SPA Vueコンポーネント(サンプルソース)

目的

 今まで書いてきた記事で作成していたASP.Net Core RazorPageでnon-SPAなVueコンポーネントの作成と、関連して作っていたTestCafeのテストコードをまとめたプロジェクトソースがある程度整ったのでサンプルs-すとして提供します。気が向いたら遊んでみてください。

前提

 ASP.NetCore RazorPage+Vue+blumaの環境を利用します。
 以前に書いた「Vue.jsを利用してみる(1)」と「Vue.jsを利用してみる(1)」を参照しての環境を構築します。

ソース

GitHUBの以下のURLに公開しています。
https://github.com/nosa67/RazorPageVue

提供内容

Vueコンポーネント

コンポーネント名 概要
vueCheckButton 複数選択可能なチェックボタン
vueRadioButton 未選択可能なラジオボタン
vueTextInput テキスト入力
vueIntegerInput 整数入力
vueRealInput 実数入力
vueTimeInput 時刻入力(サーバーではTimeSpan)
vueDateInput 日付入力(サーバーではDateTime)

バリデーション属性

バリデーション属性 概要
Required 入力必須
StringLength テキストの、最小長、最大長
Range 整数、実数、時刻の最小、最大、ステップ
Email メールアドレスかどうか
Url URLかどうか
Compare 2つのテキストの同一性

TestCafe

テストファイル 概要
VueCheckButton.test.ts チェックボタンのテスト
VueRadioButton.test.ts ラジオボタンのテスト
VueTextInput.test.ts テキスト入力のテスト
VueIntegerInput.test.ts 整数入力のテスト
VueRealInput.test.ts 実数入力のテスト
VueTimeInput.test.ts 時刻入力のテスト
VueDateInput.test.ts 日付入力のテスト

補足

 不要なコードを整理したり、バグを修正したりしていますので、今まで書いてきた記事のコードとは少し異なります。記事の方は修正しませんので、ソースを追ってください。テストコードがあるように、ある程度のテストはしていますが、まだまだバグはありますので使おうと思っているならもっとテストしてください。
 もともとの記事では、EdgeとIE11を別のコンポーネントにしていましたが、Edgeがchromiumベースになって、インターフェースがこなれたので、IE11のみ別コンポーネントになるように変更しています。
 ブラウザごとにインタフェースが異なるのを避けるなら、全て独自コンポーネントにしてもいいかもしれません。

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

【Vue.js】$emit で子 → 親 へデータを渡す

はじめに

$emitを使ったコンポーネント親子間のデータのやりとりがなかなかややこしく感じた。
なのでやったことを記録に残します。

どんなものを実装するか?

・子コンポーネントにボタンを設置。
・そのボタンをクリックすると親コンポーネントのdataの値(初期値0)に1加算された値が子コンポーネントから送られる。

実装してみる

Child.vue
<template>
  <!-- クリックでplus1メソッドを呼び出す -->
  <button @click="plus1">プラス1</button>
</template>

<script>
export default {
  props: ["childScore"],
  methods: {
    plus1() {
      // $emit('親コンポーネントで発火させる関数の名前', 処理の内容);
      this.$emit('plus-click', this.childScore + 1);
    }
  }
}
</script>
Parent.vue
<template>
  <!-- :child-score="score" で初期値を渡している。 -->
  <!-- そして@plus-clickイベントが発火したら、$event($emitで発火させたplus1メソッド処理後の値)をscoreに代入する -->
  <Child :child-score="score" @plus-click="score = $event"></Child>
  <p>{{ score }}</p>
</template>

<script>
import Child from "Child.vue"

export default {
  data() {
    return {
      score: 0,
    }
  }
}
</script>

最後に

props, $emit などコンポーネント間のデータやりとりなかなか難しい。
間違いなどなどあれば、気軽にご指摘ください。

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

【Vue.js】コンポーネント $emit で 子 → 親 へデータを渡す

はじめに

$emitを使ったコンポーネント親子間のデータのやりとりがなかなかややこしく感じた。
なのでやったことを記録に残します。

$emit とは?
Vue.js リファレンス を読んでも正直よくわかりませんでした。
この親子間のデータのやりとりに関しては、
「子コンポーネントで指定したタイミングに、親コンポーネントで処理を起こさせることができる。その処理ついでにデータを渡す。」

みたいな感じで勝手に解釈しました。(わかりずらくてすみません)

どんなものを実装するか?

・子コンポーネントにボタンを設置。
・そのボタンをクリックすると親コンポーネントのdataの値(初期値0)に1加算された値が子コンポーネントから送られる。

実装してみる

Child.vue
<template>
  <!-- クリックでplus1メソッドを呼び出す -->
  <button @click="plus1">プラス1</button>
</template>

<script>
export default {
  props: ["childScore"],
  methods: {
    plus1() {
      // $emit('親コンポーネントで発火させる関数の名前', 処理の内容);
      this.$emit('plus-click', this.childScore + 1);
    }
  }
}
</script>
Parent.vue
<template>
  <!-- :child-score="score" で初期値を渡している。 -->
  <!-- そして@plus-clickイベントが発火したら、$event($emitで発火させたplus1メソッド処理後の値)をscoreに代入する -->
  <Child :child-score="score" @plus-click="score = $event"></Child>
  <p>{{ score }}</p>
</template>

<script>
import Child from "Child.vue"

export default {
  data() {
    return {
      score: 0,
    }
  }
}
</script>

最後に

props, $emit などコンポーネント間のデータやりとりなかなか難しい。
間違いなどなどあれば、気軽にご指摘ください。

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

vueでボタンを押すと数が増えていくテンプレートを作成

count.html
<body>
    <div id="app">
        <my-counter init="0"></my-counter>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
    <script src="vue.js"></script>
</body>

Vue.component('my-counter', {
    props: ['init'],
    template: `<div>現在値は{{current}}です。
    <input type="button" v-on:click="onclick" value="増やす" /></div>`,
    data: function() {
        return{
            current: this.init
        };
    },
    methods: {
        onclick: function(){
            this.current++;
        }
    }
});

new Vue({
    el: '#app'
});
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む