- 投稿日:2020-11-14T20:32:10+09:00
VeeValidateのalpha_dashとかがeslintに叱られるとき
Vue使う人にはおなじみVeeValidateとeslintの話。
環境
- Vue 2.6.12
- VeeValidate 3.4.5
- TypeScript 4.0.5
問題
VeeValidateで用意されているルールのリストがここにありますが、例えば
alpha_dash
とかを使おうとするとeslintに叱られることがあります。ERROR Failed to compile with 1 errors8:06:23 PM error in ./src/components/Foo.vue Module Error (from ./node_modules/eslint-loader/index.js): /app/src/components/Foo.vue 111:40 error Identifier 'alpha_dash' is not in camel case @typescript-eslint/camelcase 111:40 error Identifier 'alpha_dash' is not in camel case @typescript-eslint/camelcase ✖ 2 problems (2 errors, 0 warnings)使っている
.eslintrc.js
はvue/cli
で生成したそのまま。.eslintrc.jsmodule.exports = { root: true, env: { node: true }, 'extends': [ 'plugin:vue/essential', 'eslint:recommended', '@vue/typescript/recommended' ], parserOptions: { ecmaVersion: 2020 }, rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' } }対策
VeeValidateがsnake caseで
export
してるんだから仕方ないだろとは思いつつ、このためにeslintのルールを緩めたり例外を設けるという対処はすべきではないので、以下のようにas
でエイリアス付けて回避しました。import { alpha_dash as alphaDash } from 'vee-validate/dist/rules'; extend('alpha_dash', alphaDash);これであれば
ValidationProvider
にはalpha_dash
で書けます。<ValidationProvider name="foo" rules="alpha_dash" v-slot="{ errors, valid }">
- 投稿日:2020-11-14T15:46:30+09:00
Presigned URLでAWS S3に動画をアップロードするときのファイルの渡し方
Presigned URLを使ってAWS S3に動画をアップロードするとき,ファイルの渡し方を間違えてかなり時間を無駄にしてしまったので,その知見を共有します.
結論から言うと,HTML5のFileオブジェクトをそのまま渡すとうまくいきました.
FileReaderを使ってDataURIを送ると,データが壊れてしまって再生できないようです.※注意※
- この例ではVue.js+Vuetifyを使用しています.
- ただし,やることは単純なので参考文献等を見ながら適宜読み替えてもらえば,問題ないと思います.1. 成功例
ファイルが選択されたとき,
onVideoPicked
にそのFileオブジェクトを渡しています.
そのオブジェクトをそのまま,Presigned URLでPUTすればOKでした.
この例では,他にも送信するものがあるので変数に格納しています.Presigned URLでAWS S3にアップロードする過程は,色々な事例がインターネットにありますので,そちらを参考にしてください.本記事の参考文献にもリンクがあります.
<v-file-input @change="onVideoPicked" ></v-file-input>onVideoPicked(file) { if (file !== undefined && file !== null) { if (file.name.lastIndexOf(".") <= 0) { return; } this.video = file; } else { this = ""; } }2. 失敗例
こちらの例では,ファイルが選択されたときに
FileReader
を使ってDataURIとしています.
これだと,アップロード後にファイルが壊れてしまってうまく再生できませんでした.
また,大きいファイルを選択したとき,非常に時間がかかるか,場合によっては選択できないこともありました.<v-file-input @change="onVideoPicked" ></v-file-input>onVideoPicked(file) { if (file !== undefined && file !== null) { if (file.name.lastIndexOf(".") <= 0) { return; } const fr = new FileReader(); fr.readAsDataURL(file); fr.onload = () => { this.video = fr.result; }; } else { this.video = ""; } }3. 終わり
フロントエンドは罠がいっぱいだと思いました!
4. 参考文献
- 投稿日:2020-11-14T14:06:44+09:00
【Vue.js 再入門】 v-model を正しく理解して親子コンポーネント間のデータ伝播をマスターする
はじめに
Vue.js のコンポーネント間のデータのやりとりについて、親コンポーネントから子コンポーネントへデータを渡すには、
v-bind
属性とprops
オプションを利用します。これにより親コンポーネント側でデータを変更すれば、子コンポーネントのprops
経由で渡されたデータも変更されます。しかし、子コンポーネント側でprops
経由で渡されたデータを直接変更することは非推奨です。しかし、子コンポーネントの変更を親コンポーネントへ反映したい場合があります。たとえば、再利用性のある入力フォームのコンポーネントを親子間でやりとりするケースです。この問題を解決するには v-model を正しく理解する必要があります。御復習い
v-model は双方向データバインディングを実現するディレクティブです。双方向データバインディングとは、ビューで変更があった場合、その値を Vue インスタンスのデータとして更新します。逆に Vue インスタンスのデータに変更があった場合はビューを再レンダリングします。
<input v-model="message" />v-model は以下のコードの糖衣構文になります。
糖衣構文<input :value="message" @input="message = $event.target.value" />さらにコンポーネントの v-model の糖衣構文は以下のようになります。
コンポーネントの糖衣構文<custom-input :value="message" @input="message = $event" ></custom-input>本題
子コンポーネントの変更を親コンポーネントへ反映する方法を紹介します。まずは親コンポーネントについて説明します。まずは、
v-bind
属性経由で子コンポーネントにデータ(message
)を渡すための準備をします。props
は親コンポーネントのv-bind
属性経由で渡します。親コンポーネント<!-- コードは一部省略しています。 --> <custom-input :value="message"></custom-input> <script> export default { data() { return { message: "", }; }, }; </script>
v-bind
属性経由で渡されたデータは子コンポーネントのprops
オプションで定義します。子コンポーネント<script> // props オプションの定義 export default { props: { value: { type: String, }, }, }; </script>上記のように
props
オプションを定義すれば、コンポーネントをインスタンス化したときにオブジェクトのプロパティとして利用できます。つまり、data
と同様にテンプレート中で展開できます。それでは子コンポーネントのvalue
属性にprops
で定義したvalue
をv-bind
属性でバインディングしましょう。子コンポーネント<input :value="value" />子コンポーネントから親コンポーネントへの通信では、
$emit
メソッドでイベントを送出します。それでは子コンポーネントの入力イベントを親コンポーネントへ通信するための準備をしましょう。子コンポーネント<input :value="value" @input="$emit('input', $event.target.value)" />
input
イベントをハンドリングして、$emit
メソッドで親コンポーネントにイベントを送出します。$emit
メソッドの第 2 引数には子コンポーネントで入力された値を指定します。これにより親コンポーネントのv-on
ディレクティブを使ってイベントを受け取る際、子コンポーネントで入力された値を取得できます。親コンポーネント<custom-input :value="message" @input="message = $event" ></custom-input>親コンポーネント側でも
input
イベントをハンドリングして、子コンポーネントで入力された値を親コンポーネントで管理しているmessage
に代入します。これで子コンポーネントの変更を親コンポーネントへ反映できます。しかし、このままでは少し冗長なのでもう少しスッキリした書き方があります。それが v-model です。v-model をカスタムコンポーネントで利用する場合、上記の糖衣構文になります。親コンポーネント<custom-input v-model="message"></custom-input>ちなみに子コンポーネントでも同様に v-model を利用したい場合は、算出プロパティの getter 関数と setter 関数を利用します。算出プロパティはデフォルトでは getter 関数のみですが、必要があれば setter 関数も使えます。
子コンポーネント<!-- v-model を利用した場合 --> <template> <input v-model="inputedValue" /> </template> <script> export default { props: { value: { type: String, }, }, computed: { inputedValue: { get() { return this.value; }, set(newValue) { this.$emit("input", newValue); }, }, }, }; </script>
input
イベントでハンドリングして、v-bind
属性でバインディングしたvalue
属性を setter 関数の引数に渡し、$emit
メソッドで親コンポーネントに入力されたデータを伝播します。いかがでしょうか。どちらも v-model を正しく理解していなければ一見なにをやっているのか把握しにくいかと思います。v-model に限らず正しく仕様を理解することは重要です。当記事の内容がどなたかの一助になれば幸甚です。サンプルコード
▼ v-model を利用しないサンプルコード
▼ v-model を利用したサンプルコード
参考文献
- 投稿日:2020-11-14T11:27:36+09:00
Laravel + Vue + TypeScript + Eslint
この記事ではLaravelのフロントエンドをVue+TypeScriptで実装します。
TypeScriptの整形にはESlintを使用します。使うもの
- Laravel Laravel_Mix
- TypeScript ESlint
- Vue Vue-Router使わないもの
- TSlint Pretter環境
- Laravel v7.5
- Node v13
- Vue v2.6
準備
Laravelのプロジェクトを作成
bash
composer create-project --prefer-dist laravel/laravel app
Vueをインストールする
bash
npm i
npm i -D vue vue-router vue-template-compiler
npm i -D typescript ts-loader
npm i -D eslint eslint-plugin-vue @typescript-eslint/eslint-plugin @typescript-eslint/parser
追加・修正するファイル一覧
├---resources | ├---ts(追加) | | ├---App.vue | | ├---app.ts | | ├---pages | | | └---index.vue | | ├---route.ts | | └---vue-shim.d.ts | └---views | └---index.blade.php(追加) ├---routes | └---web.php(修正) ├---.eslintrc.json(追加) ├---tsconfig.json(追加) └---webpack.mix.js(修正)ルートとテンプレートを追加修正
routes/web.php
php
Route::get('/{any?}', function () {
return view('index');
})->where('any', '.+');
resources/views/index.blade.php
{{ config('app.name') }}
```html
<!doctype html>
<!-- Scripts -->
<!-- Fonts -->
<!-- Styles -->
- 投稿日:2020-11-14T11:11:05+09:00
Laravel関連 (個人的)命名規則
Laravelとその周辺の命名規則を個人的なものも含めてまとめたメモ
2020/06/18 Vueを追加ソースコード
モデル名 EditUser (単数形、パスカルケース)
コントローラー名 EditUsersController (単数形か複数形、パスカルケース)
ビュー edit_users/create.blade.php (単数形か複数形、スネークケース)
- コントローラーとビューには同じ規則を適用
データベース
テーブル名 edit_users (複数形、スネークケース)
カラム名 second_name (スネークケース)
外部キー edit_user_id (モデル名_id)
中間テーブル post_tag (モデルのアルファベット順、スネークケース)edit_users (id int, name string, second_name string) posts (id int, body string, edit_user_id int) tags (id int, name string) post_tag (id int, post_id int, tag_id int)PSR-2
クラス名 EditUsersController (パスカルケース)
メソッド名 createEditUser (キャメルケース)
変数 $edit_user (スネークケース)
定数 MAX_USER (大文字 + _)
- 名前は長くても20文字程度
Javascript
オブジェクト・関数・インスタンス (キャメルケース)
js
var thisIsMyObject = {};
function thisIsMyFunction() {}
var user = new User({
name: 'Bob Parr'
});
クラス・コンストラクタ (パスカルケース)
```js
function User(options) {
this.name = options.name;
}var good = new User({
name: 'yup'
});
```
定数 MAX_USER (大文字 + _)
プライベートメンバ _internalFunction (_ + キャメルケース)
イベントハンドラ onDialogAccept (on + パスカルケース)Vue
ファイル名 ((Base, App, V + )パスカルケース) 複数単語にする
コンポーネント パスカルケース
propsを渡す側 ケバブケース
ptopsを受け取る側 キャメルケース
js
<UserListItem first-name="satou" />
...
export default {
props: {
firstName: String
}
}
HTML
class属性 CSSで使用するのでケバブケース
id属性 JavaScriptで使用するのでキャメルケース
data-*属性 JavaScriptで使用するのでキャメルケースその他
ルート http://abc.de.jp/play-histories/{play_history} (ケバブケース)
- 変数はスネークケース
- 基本は小文字で統一
参考
https://laraweb.net/knowledge/942/
https://qiita.com/Takashi_INOUE/items/41d9fedaad1ff338cada
http://snowdream.github.io/javascript-style-guide/javascript-style-guide/jp/naming-conventions.html
https://www.asobou.co.jp/blog/web/url-optimisation
https://qiita.com/itagakishintaro/items/168667d5ee4c56b30d52
https://qiita.com/ngron/items/ab2a17ae483c95a2f15e
- 投稿日:2020-11-14T09:47:38+09:00
【保存版】Vue.jsでFontAwesomeを簡単に使う方法
はじめに
本記事へのアクセスありがとうございます。
投稿主はプログラミング初心者であり、この方法が「最適解」かは分かりません。
しかし、動作は検証済みです。こんなやり方もできるんだ〜程度に見てもらえれば幸いです。
さっそくスタート
まずはVue.jsでFontAwesomeを使うにあたり、必要となる5つを先にダウンロードしていきます。
この記事ではyarnでダウンロードを記載していきますが、npmの方はnpmのダウンロード方法でお願いします。yarn add --dev @fortawesome/fontawesome-svg-core @fortawesome/free-brands-svg-icons @fortawesome/free-regular-svg-icons @fortawesome/free-solid-svg-icons @fortawesome/vue-fontawesomewebpackのentry先であるjs(ここではmain.js)に下記のコードを追記します。
import { library } from '@fortawesome/fontawesome-svg-core'; import { fas } from '@fortawesome/free-solid-svg-icons'; import { far } from '@fortawesome/free-regular-svg-icons'; import { fab } from '@fortawesome/free-brands-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; library.add(fas, far, fab); Vue.component('font-awesome-icon', FontAwesomeIcon);FontAwesomeのホームページから使用したいアイコンを選択します。
今回は下記のアップルのアイコンを例として使いたいと思います。
<div> <p>アップル</p> <font-awesome-icon :icon="['fab', 'apple']" />このコードでアップルという文字の隣にアイコンを配置すること出来ます。
ポイントは:icon内の記載を上記画像の赤矢印のように書く事です。また、下記のように font-awesome-iconタグにオプションとしてサイズや色を付け加えることもできます。
<div> <p>アップル</p> <font-awesome-icon :icon="['fab', 'apple']" style="color: red" size="2x" />ボタンのアイコンとして使用したい場合は下記のようにすればOKです。
<div> <button @click="〇〇"> <font-awesome-icon :icon="['fab', 'apple']" style="color: red" size="2x" /> </button>おわり
お疲れ様でした。これでVue.jsにおけるFontAwesome設定が完了です。
少しでも役に立ったと思う方がいましたらLGTMをお願いします?♂️
- 投稿日:2020-11-14T08:59:22+09:00
【nuxt.js】FontAwesomeを「軽く」使用する方法
nuxtアプリにFontAwesomeを導入する際、より「軽く」するためのメモになります。
前提
nuxtにFontAwesomeをインストールする方法は、公式ドキュメントに載っていますので割愛します。(要約して記事にしている方も多いですし)
参考:nuxt-fontawesomeFontAwesomeは重い
FontAwesomeは普通に実装すると結構重いです。そのため、軽くするための工夫が必要になります。
以下のように使用するアイコンの名前を直接指定すると、指定されたアイコンのみ読み込みます。nuxt.config.jsfontawesome: { imports: [ { set: '@fortawesome/free-solid-svg-icons', icons: ['faBars', ],//['fas']だと全て読み込んでしまう }, ], },状況にもよるかと思いますが、私のプロダクトの場合は体感で3~4秒ほど初期ロードが短縮されました。