- 投稿日:2020-03-18T23:38:34+09:00
【Vue】喘ぎ声メーカー作ってみた
スーパー喘ぎ声メーカー
用意した単語をシャッフルして喘ぎ声を生成するツールを作ってみました。
喘ぎ声に限らず、好きな単語を入れて遊べます。何故作ろうと思ったのか
BL小説書きの友人が「この喘ぎ声の組み合わせさっきも書いたな?
となるので自動生成してくれるツールがほしい」と言っていたので。
BLに限らずいやらしい小説を書く方への負担を少しでも減らせないかと思い、作成にいたりました。
あとVueの勉強になりそうだと思ったので。
筆者は文系のwebデザイナー(見習い)であり、プログラミングの分野は勉強中です。使ったもの
- HTML
- CSS
- JavaScript
- clipboard.js
- Vue.js
- jQuery
- Bootstrap4
- Font Awesome
作成の流れ
プロトタイプ①
まずHTMLとJavaScriptのみでプロトタイプを作成。
「生成!」ボタンを押すと配列をシャッフルした結果が表示されます。
決め打ちのデータしか組み合わせられませんが、大体のイメージができあがりました。ちなみに「やっそん(おそらく「やめて、そんな」→「やっ…そん…」→「やっそん」と転じた)」は
一部界隈のスラングでBLの性行為のことを指します。永遠に使えないムダ知識をあなたに。使用例:出会って5秒でやっそん
プロトタイプ②
Vue.jsでよくあるTodoアプリのコードを元にプロトタイプ第二弾を作成。
入力したデータを組み合わせられるようになった点はいい感じです。Vue.jsrandom: function () { const rnd = Math.floor(Math.random() * this.words.length); return this.words[rnd]; }ただこのメソッドだと同じ単語を何度も使ってしまうため、「あっあっあっ」と
ネフェルピトーに脳を弄くられるポックルみたいになってしまいます。
配列をシャッフルするコードに書き換えなければなりません。モックアップ
Bootstrap4で見た目だけのものを作成。レスポンシブにも対応です。完成品
完成品がこちらです!→スーパー喘ぎ声メーカー
Vue.jsvar vm = new Vue({ el: '#app', data: { newItem: '', array: [ 'やっ', 'あっ', 'んっ…', ], }, methods: { addItem: function () { this.array.push(this.newItem); this.newItem = ''; }, deleteItem: function (index) { this.array.splice(index, 1); }, shuffle: function (array) { var sArray = []; sArray = array.slice(0, array.length); var n = sArray.length, t, i; while (n) { i = Math.floor(Math.random() * n--); t = sArray[n]; sArray[n] = sArray[i]; sArray[i] = t; } return sArray.join(''); }, reset: function () { this.array = [] } } });長くなるのでVue部分だけ掲載。(HTML含む全文はgithubで公開してます)
Vue.jsshuffle: function (array) { var n = array.length, t, i; while (n) { i = Math.floor(Math.random() * n--); t = array[n]; array[n] = array[i]; array[i] = t; } return array.join(''); }これは過去のコードなのですが、このメソッドだと
シャッフル実行時配列そのものもシャッフルされてしまいます。下図参照。
Vue.jsshuffle: function (array) { var sArray = []; sArray = array.slice(0, array.length); var n = sArray.length, t, i; while (n) { i = Math.floor(Math.random() * n--); t = sArray[n]; sArray[n] = sArray[i]; sArray[i] = t; } return sArray.join(''); }コピーした配列にシャッフル処理をするように書き換えたら
単語のリストはシャッフルされなくなりました。
この対処法が正しいかはわかりませんが…
また生成結果を表示するリストは、idを個別に用意するために
clipboard-target1~clipboard-target10までわざわざ一つ一つ<li>
要素を作成していました。
何故idを個別に用意する必要があるのかと言うと、
clipboard.jsで特定のdivのテキストをコピーするために
個別のターゲットを指定しなければならないからです。
data-clipboard-target
の指定先がid名になっているのがお分かりいただけると思います。でもVueならもっとスッキリ書けるんじゃないか?とよく考えたら、
v-for
のループ処理でなんとかできそうだと思い至る。HTML<li v-bind:id="`clipboard-target${n}`" class="clipboard-target mb-2" v-for="n in 10"> <span>{{ shuffle(array) }}</span> <div class="btn btn-danger btn-sm ml-3 btn-clipboard" data-toggle="tooltip" v-bind:data-clipboard-target="`#clipboard-target${n}`"> コピー </div> </li>
v-bind
とv-for
でidとdata-clipboard-targetが連番になった<li>
要素を10個作ることができました。
v-for="n in 10"の10の部分を変更すれば、喘ぎ声セットを10個でも100個でも作成できますね!
JavaScriptでやったら多分めちゃくちゃ面倒くさい処理ですよね…
ありがとうVue。感想
- 明確な目的があったためVue勉強のモチベーションが保ててよかった
- 友達にややウケした
課題・問題点
- 双方向バインディングすぎてEnterを押すたびに結果が再生成される
- 最初のイメージに合わせる知識がなかった(本当は「生成」ボタン押下時に結果が表示されるようにしたかった)
- 一度リセットしてから再度単語を追加して生成すると、ツールチップが表示されない(コピー自体は問題なくできる)
- 本当はVueのコンポーネント機能を使いたかったが調べてもわからなかった
GitHubでコードを公開しておりますので、アドバイスいただけたら嬉しいです。
https://github.com/mitaru/superxxxmaker
コード見たら私がマジの初心者であることはお分かりになるかと思います…
プルリクお待ちしております。
- 投稿日:2020-03-18T22:49:58+09:00
Vue.js 現在時刻の表示 ~時計~
Vue.jsとは
ユーザーインターフェイスを構築するためのプログレッシブフレームワークです。他の一枚板(モノリシック: monolithic)なフレームワークとは異なり、Vue は少しずつ適用していけるように設計されています。中核となるライブラリは view 層だけに焦点を当てています。そのため、使い始めるのも、他のライブラリや既存のプロジェクトに統合するのも、とても簡単です。また、モダンなツールやサポートライブラリと併用することで、洗練されたシングルページアプリケーションの開発も可能です。
Vue.jsを使用するメリット
- 気軽に使える: Vue.js はjQueryと同様に、scriptタグを1行書くだけで使い始めることができます。
DOM操作を自動的に行ってくれる:
HTMLドキュメント全体の要素の構成をDOM(Document Object Model)といいます。Vue.jsはHTML側の要素とJavaScript側の値やイベントとの対応付を自動で行ってくれます。これにより、jQueryよりも簡潔に分かりやすくコードを記載することができます。学習コストが低い:
AngularやReactと比較してフレームワークの規模が小さい分、覚えることも少なくて済みます。JavaScriptやjQueryの基礎知識があれば数時間の学習で開発を開始することができるでしょう。Vue.jsで現在時刻を取得して表示する
初めに全体像を掴んでもらうために、完成品を記述します。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <p>{{ now }}</p> <button v-on:click="time">現在時刻</button> <!-- v-on:event --> </div> <!-- Vue.jsをインストール --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- ここから記述していきます --> <script> let app = new Vue({ el: "#app", data:{ now: "00:00:00" }, methods: { time: function(e){ function(e) var date = new Date(); this.now = date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); } } }); </script> </body> </html>完成品
ここから要素ごとに説明していきます。ちなみにVue.jsは始めたばかりになるので、説明が至らぬところがあればコメントお願いします。
<div id="app"> <p>{{ now }}</p> <button v-on:click="time">現在時刻</button> <!-- v-on:event --> </div>まずはHTMLでのこちら。
{{ }}
こちらの記述がJavaScriptのメッセージに自動的に置換してくれます。
v-on
v-on ディレクティブを使うことで、DOM イベントの購読、イベント発火時の JavaScript の実行が可能になります。次にコメントアウトにてscript以降の説明していきます。
let app = new Vue({ el: "#app", //el: "ID要素"を取得します data:{ //こちらのプロパティでHTMLの{{}}を置換します }, })次にmethod以降の説明していきます。
let app = new Vue({ el: "#app", data:{ now: "00:00:00" //now: == {{}} }, methods: { time: function(e){ //function(e) この引数eは、eventの「e」 let date = new Date(); //new演算子でオブジェクトのインスタンスを生成 //現在時刻の取得 **ここからはjavascript** this.now = date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); } } });ボタンを押す前
どうでしょうか?
クリックイベントで、現在の時間を取得できましたか?私もまだまだ勉強中ですが、書き方自体はシンプルでとてもわかりやすいですよね。
ちなみに私はこちらをYoutubeで見て学習をしました。
是非そちらもご参考までに見てみてください。Youtube たにぐち まことのともすたチャンネル様
https://www.youtube.com/watch?v=jdcZ3LvTs78
- 投稿日:2020-03-18T22:33:10+09:00
Vuexのmutations/actionsが実行された事をテストする方法を調べたメモ
Store側のテストについては言及があっても、コンポーネント側のテストについてはあまり見かけなかったので調べた内容をメモ。
結論コード
概要
- Vuex Storeを用意するよ
- mutationsのStubを用意するよ
- 上2つをセットしたwrapperでcalledを見るよ
コード
ButtonStuff.vue<template> <button type='button' @click='doSomething' > Do something </button> </template> <script> export default { name: 'ButtonStuff', props: { // some properties }, methods: { doSomething () { // Mutation this.$store.commit('doStoreMutation', { hoge: 'hoge', foo: 'foo' }) } } } </script>ButtonStuff.spec.jsimport Vuex from 'vuex' import chai, { expect, assert } from 'chai' import sinon from 'sinon' import sinonChai from 'sinon-chai' import { shallowMount, createLocalVue } from '@vue/test-utils' import Component from '@/components/Atoms/ButonStuff.vue' chai.use(sinonChai) const localVue = createLocalVue() localVue.use(Vuex) describe('ButtonStuff.vue', () => { describe('Events', () => { describe('Click', () => { let store // 実際のMutationと同じ名前にする。 const mutations = { doStoreMutationA: sinon.stub(), doStoreMutationB: sinon.stub(), doStoreMutationC: sinon.stub() } beforeEach(() => { store = new Vuex.Store({ state: {}, mutations }) }) it('should be triggered the mutation', () => { const wrapper = shallowMount(Component, { store, localVue }) wrapper.find('button').trigger('click') assert(mutations.doStoreMutationA.called) }) }) }) }) })※ mutationsを例に書いていますが、actionsも同じ方法でいけるはず。
ハマった所
- テストコード側の
mutations
オブジェクトに用意したmutationの名前は実際のstoreにあるmutation名と合わせるところ。あまり意識せずにdoStoreMutationMock
みたいにしたらキックされなくて悩んだ- JestとMocha&chaiでの書き方の違い、それぞれの記法でもう片方はどうするか、実際できるのかがわからず調べるのに時間がかかった。
assert
を使ってるけど、本当はexpect
でやりたいが、書き方がまだわかってない(何パターンか試したがコケる)のでこの項目に関してassert
で妥協している
- 投稿日:2020-03-18T21:16:04+09:00
Vue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part6
前回のパート
前回はログアウト機能の実装を行いました
前回で認証まわりの実装が終わったので、今パートからはTodo機能の実装に入っていきます
前回のパートはこちらVue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part5Todoリストの機能
まず、今回のTodoリストの機能をおさらいしておきます
Todoリストの実装する機能は下記の4点になります
削除や新規作成の際などにアニメーションは付けないシンプルなものになっていますので
アニメーションが欲しい方は、一通り実装が終わった際に自身で挑戦してみてください
- todoの一覧表示
- todoの新規追加
- todoの更新
- todoの削除(完了時)
それでは、上記の4点の実装を行っていきます
まず最初に新規Todoの追加機能の実装から入りますLaravel側の実装
まずはコントローラーの作成を行います
上記の機能で確認した通り、表示,追加,更新,削除の機能なので
Todo専用の一つのコントローラーである
リソースコントローラーを作成しそれを利用していきますコマンドにて下記を実行しコントローラーの作成を行ってください
$ php artisan make:controller TodoController --resource
実行で作成されるのが下記のファイルになっているかと思いますTodoController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Todo; use Log; class TodoController extends Controller { public function index() { // } public function create() { // } public function store(Request $request) { // } public function show($id) { // } public function edit($id) { // } public function update(Request $request, $id) { // } public function destroy($id) { // } }リソースコントローラーについて、わからない方はこちらを参照ください→こちら
これで、Todoに関する全ての処理を行うコントローラーの作成が終わりました
次にapi.php
に作成したリソースフルコントローラーのルートを定義します
api.php
を開いて下記を追加してくださいapi.php<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/register', 'Auth\RegisterController@register')->name('register'); Route::post('/login', 'Auth\LoginController@login')->name('login'); Route::post('/logout', 'Auth\LoginController@logout')->name('logout'); Route::get('/user', function(){ return Auth::user(); }); Route::resource('/todo', 'TodoController'); //追加もう少しLaravel側での実装がありますが
一旦Vue側の実装に移りますVue側の実装
それでは次に、Vue側で既に作成した
Todo.vue
を開きそちらを編集していきます
Todo.vue
を開いて下記を追加してください
内容については、一つづ説明していきますTodo.vue<template> <div> <Header /> <div class="main-container"> {{ user.name }}のTodoリスト //・・・① <v-text-field v-model="text" label="todo" required></v-text-field> <v-btn class="btn" @click="create">登録</v-btn> //・・・② <template v-for="item in items"> <v-card max-width="450" class="mx-auto" style="marign-top: 10px" :key="item.id"> <v-list three-line> <v-list-item :key="item.id"> <v-list-item-content> <input type="text" v-model="item.text"> //・・・③ <v-btn small>完了</v-btn> </v-list-item-content> </v-list-item> </v-list> </v-card> </template> </div> </div> </template> <script> import Header from './Header'; import axios from 'axios'; export default { components: { Header }, metaInfo: { title: 'Todo', htmlAttrs: { lang: 'ja' } }, created () { //・・・④ const user = this.$store.getters['auth/user']; if (user === null) { this.$router.push('/login'); } }, computed: { user() { //・・・⑤ return this.$store.getters['auth/user']; } }, data () { return { items: [ //・・・⑥ { id: 1, text: 'テスト'}, { id: 2, text: 'テスト'} ], text: '' } }, methods: { async create() { //・・・⑦ await axios.post('/api/todo', { user_id: this.user.id, text: this.text }); this.$router.go({ path: this.$router.currentRoute.path, force: true }); } } } </script> <style> .main-container { width: 500px; margin: auto; } .btn { margin-bottom: 20px; } </style>①は認証ユーザーの情報のVuexで保管してるデータを所得して、ユーザーの名前を表示しています
②クリックイベントでtodoの登録処理のメソッドを発火させます
③今後の機能実装でtodoの内容を表示し書き換えて変更など出来る様に<input>
にv-modelで現在のダミーのデータを表示しています
④ログインしているかをチェックしています。ログインしていなければ/login
にリダイレクトされる様にしています
⑤こちらは①でユーザー名を参照するためにcomputedを使ってauth.jsのgetterを利用してstateのuserの情報を所得しています
⑥現在はtodo内容の表示機能がないため、ダミーデータを配置してます
⑦実際のtodoの登録処理のメソッドになります。詳しくは下で話します⑦のメソッドについて説明します
ここで行っている処理は、フォームに追加したいtodoの内容が入力され登録ボタンが押されると
Laravel側の先ほど定義した/todo
に対してPOSTリクエストを送信します
そうすることでLaravelで作成したTodoController.php
のstore()
アクションが呼び出されます
store()
には登録したい内容であるユーザーのIDとtodoの内容を送ります
それがここの第二引数で指定していますawait axios.post('/api/todo', { user_id: this.user.id, text: this.text });
これを受け取ったLaravel側のTodoController.php
のstore()
アクションがDBに登録処理を行います
その処理が完了すれば、現在のパスにリダイレクトする様にしています
それがこの部分になりますthis.$router.go({ path: this.$router.currentRoute.path, force: true });
上記で登録処理をするにあったって、Vue側で必要な実装は完了しましたので
残るは、TodoController.php
のstore()
アクションの実装を行えば登録ができるようになりますstore()アクションの機能実装
それでは、VueからリクエストでPOSTされて送られてきたデータをLaravel側でDBに登録する処理を
store()に記述していきます
TodoController.php
を開きstore()
に下記を追加してくださいTodoController.phppublic function store(Request $request) { Todo::create($request->all()); return response('', 200); }$request->all()でVue側で送ったユーザーのIDとtodoの内容が受け取れます
それをTodo::create()
で新規で登録を行っています次に
Todo::create($request->all())
を実行するためにTodoモデル
の作成と編集を行います
コマンドにて下記を実行してください
$ php artisan make:model Todo
上記を実行することで、app
ディレクトリ配下にTodo.php
が作成されます
これが、todosテーブルと紐づいたTodoのモデルになります
それでは、Todo.php
に下記を追加してくださいTodo.php<?php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; //追加 class Todo extends Model { use SoftDeletes; //追加 protected $fillable = [ //追加 'user_id','text' ]; }ここではSoftDeletes(論理削除)を利用するための記述と
$fillabel
を追加しました論理削除は
Illuminate\Database\Eloquent\SoftDeletes
をuseで追加しモデル内でuse SoftDeletes
とすることで利用できます
protected $fillabel
ここでuser_id
とtext
を指定してます
todosテーブルのuser_idとtextを一括で更新をすることを許可しています
これを行うことで、先ほど記述したstore()
内の処理Todo::create($request->all())
で登録が行えますこれでtodo登録に必要な処理は一通り実装できました
一度フォームに入力して登録ボタンをクリックしてみてください
その後、DBのtodosテーブルに実際に登録できているかを確認してみてください
無事データがあれば完了です確認方法が分からない方は、このまま一旦進んでください
次回のパートで表示機能を作りますので、そこで正常に登録が行えてるのかも確認できます終わりに
今回は、todoの登録機能を実装しました
残る機能は、表示,更新,削除です
次回、表示機能の実装を行っていきます次回のパートはこちら→Vue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part7
- 投稿日:2020-03-18T19:52:02+09:00
Vue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part5
前回のパート
前回は、ログイン機能の実装と
Todo.vue
ページの作成を行いました
今回はログアウト機能を実装していこうと思います
今回のパートで会員登録、ログイン、ログアウトの機能が揃いますのでようやく、Todoリストの機能実装に移れそうです
前回のパートはこちら→Vue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part4Laravel側の実装
Laravel側の実装はルートの定義のみです
api.php
に下記のルートを追加してくださいapi.php<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/register', 'Auth\RegisterController@register')->name('register'); Route::post('/login', 'Auth\LoginController@login')->name('login'); Route::post('/logout', 'Auth\LoginController@logout')->name('logout'); //追加 Route::get('/user', function(){ return Auth::user(); });Header.vueの編集
Header.vue
でLogoutのクリックアクションを追加していきます
Header.vue
で下記を追加してくださいHeader.vue<template> <v-card color="grey lighten-4" flat height="200px" tile> <v-toolbar dense> <v-app-bar-nav-icon></v-app-bar-nav-icon> <v-toolbar-title>Todo-List</v-toolbar-title> <v-spacer></v-spacer> <router-link to="/signup"> <v-btn icon> <v-icon>mdi-account</v-icon> </v-btn> </router-link> <router-link to="/todo"> <v-btn icon> <v-icon>mdi-align-horizontal-left</v-icon> </v-btn> </router-link> <router-link to="/login"> <v-btn icon> <v-icon>mdi-login</v-icon> </v-btn> </router-link> <v-btn icon @click="logout"> //追加 <v-icon>mdi-logout</v-icon> </v-btn> </v-toolbar> </v-card> </template> <script> //追加 export default { methods: { async logout() { await this.$store.dispatch('auth/logout'); this.$router.push('/login'); } } } </script>ヘッダーのLogoutのアイコンをクリックする事で、イベントを発火させ
logout()
メソッドを呼び出す様に変更しました
次に、logout()
で呼び出してるauth.js
側の処理を追加していきます
auth.js
のアクションに下記を追加してくださいauth.jsimport axios from 'axios'; const state = { user: null } const getters = { user: state => state.user } const mutations = { setUser (state, user) { state.user = user; } } const actions = { async register({ commit }, data) { const response = await axios.post('/api/register', data) commit('setUser', response.data); }, async searchUser({ commit }) { const response = await axios.get('/api/user'); const user = response.data ? response.data : null; commit('setUser', user); }, async login({ commit }, data) { const response = await axios.post('/api/login', data); commit('setUser', response.data); }, async logout({ commit }) { //追加 await axios.post('/api/logout'); commit('setUser', null); } } export default { namespaced: true, state, getters, mutations, actions }ここまでの実装で説明をしていきます
まず、
Header.vue
のログアウトアイコンがクリックされる事で
auth.js
のactionsであるlogout()
が呼ばれます
logout()
の中でLaravel側で定義した/logout
にルーティングされ、ログアウト処理が実行されます
ログアウト処理が完了したところで、commit('setUser', null)
としてstateのUserを空にして
ログアウト状態である事にしていますログアウト処理は以上になります
一度ログインを行い、その後ログアウトを行ってみてください
正常であれば、Login.vueのページに戻るはずです終わりに
今回はログアウト機能を作成しました
今回で会員登録からログイン、ログアウトと認証まわりの実装が全て終わりましたので
次のパートから、Todo.vue
のTodoリストの実装に入っていこうと思います次回のパートはこちら→Vue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part6
- 投稿日:2020-03-18T18:31:45+09:00
laravel環境構築 および migrateができず詰まったのメモ
環境構築の手順
1 create your own .env file / .envファイルを作る
cp .env.example .env.local
* .env.local is generally included in the .gitignore / .gitignoreファイルに.env.localが基本的に含まれている
Create your database, and put the login information in the .env.local file / データベースを作成し、ログイン情報を.env.localファイルに入れる
2 Copy your .env.local file to .env / .env.local ファイルを .env ファイルにコピーする
cp .env.local .env
3 Run composer / composer を実行する
composer update
4 Run npm install / npm install を実行する
npm install
5 Run npm / npm を実行する。 *npm updateしないとダメかも(下のハマったことに記載)
npm run dev
6 Create key / key を生成させる
php artisan key:generate
7 Run migration and seed / migrationとseed を実行する
php artisan migrate
php artisan db:seed
8 Serve on local machine / ローカルでホストする/サーバーの起動
php artisan serve
当たり前にローカルにデータベース作り忘れてたらダメ
ハマったこと
php artisan migrateの失敗
画像のようなエラーが発生した。
以下の記事を参考に設定したが、上手くいかず。
【Laravel】初期設定でDB設定(MySQL)にハマったので抜け方解説
database.phpと.envの設定を確認するもだめだった..
dbへの接続を確認することにした。もしかしたらパスワードが間違っているかもしれない。
そこで、$ mysql -u root -p
で確認したら、そもそもパスワード設定してなかったわ笑migrateした時には.envファイルdatabase.phpより優先的に読み込まれるので、.envファイルのパスワードを変更したらいけた。
しょうもないことに時間をかけてしまったnpm install の失敗
npm install
を実施するとエラーが発生。
npmパッケージで脆弱性がある場合に出るらしい。そこで、
1. npm audit fix
2. npm update ←これで脆弱性のパッケージの自動修正してくれる
3. npm isntall
- 投稿日:2020-03-18T18:09:37+09:00
Vue.js セットアップメモ(Mac)
この記事の目的
Vue.jsの学習を始める際に実施したセットアップ手順のメモです。
開発環境、必要なもの
- Mac OS Catalina 10.15.2 ←自分の場合(参考程度)
セットアップ
ndenvのインストール
- 複数バージョンのNodeを切り替えて使用することになると思いますので、
ndenv
をインストールします。$ brew install ndenv
- PATHを追加します
echo 'export PATH="$HOME/.ndenv/bin:$PATH"' echo 'eval "$(ndenv init -)"'
- Nodeをインストールするために
node-build
をインストールします。$ git clone https://github.com/riywo/node-build.git $(ndenv root)/plugins/node-buildNode.jsのインストール
- インストールできるNode.jsバージョンを確認
$ ndenv install -l
- Node.jsのインストール
$ ndenv install v12.16.1 #LTS版がおすすめ
- 使用するNode.jsの設定
$ ndenv versions # インストールしているNode.jsのバージョンを確認する $ ndenv global v12.16.1 # デフォルトバージョンを設定するとき $ ndenv local v12.16.1 # プロジェクトごとに変更するとき
- Node.jsのバージョン確認
$ node --versionVue.jsのインストール
- Vue CLIのインストール
$ npm install -g @vue/cli
- Vue cli-service-globalのインストール
$ npm install -g @vue/cli-service-global動作確認
- vueファイルを作成します。
$ cat app.vue <template> <div id="app"> <h1>Hello World</h1> </div> </template>
- 実行する
$ vue serve
- ブラウザで確認する。
- http://localhost:8080 にアクセスしてみてください。
- 期待通りにブラウザに表示されていたら、セットアップ完了です!
終わりに
- 最低限のセットアップになりますが、上記の手順で一通りの実行環境は整います。
- editor用のプラグインの設定等の設定も追記予定です。
補足
- Google Chrome用に
vue-devtools
をインストールしておくのも必須のようです。
- 投稿日:2020-03-18T11:30:01+09:00
addEventListenerにアロー関数で値を渡すとremoveEventのとき困る
mountedでイベントリスナーを動かし、destroyedで削除するパターンでうまくイベント削除が行えなかったのでメモ。
下記はVueを使っていますが、別にVueに限らず問題起こるみたい。
mounted () { window.addEventListener('mousedown', (e) => { this.hoge(e) }) }, destroyed () { window.removeEventListener('mousedown',this.hoge) }, methods: { hoge (e) { console.log(e.clientX) } }下記のように書き換えました。
mounted () { window.addEventListener('mousedown', this.hoge) }, destroyed () { window.removeEventListener('mousedown',this.hoge) }, methods: { hoge (e) { console.log(e.clientX) } }
- 投稿日:2020-03-18T10:34:06+09:00
Nuxt2.12.0で新しくなったfetchについて
Nuxt2.12.0でfetch methodが新しくなりました。
https://github.com/nuxt/nuxt.js/releases/tag/v2.12.0
...fetch?
っていうか、fetchって使います? 多分使わないと思います。なぜならasyncDataと機能的にほぼ同じなので。fetchにできることは全部asyncDataで出来ていました。
新しくなったというか、ついに定義された真のfetch
で、2.12からは完全に新しくなりました。将来的にはむしろasyncDataを不要にしていくと思います(後述)
APIドキュメント: https://nuxtjs.org/api/pages-fetch
要点としては
- pageComponent限定の機能ではなくなった
- fetch methodの引数にcontextを受け取らなくなったかわりに、thisが使えるようになった(なのでpropを用いたfetchなどが可能に)
- thisに
$fetch
,$fetchState
が生えたthis.$fetch()
で再実行ができるようになったというあたりです。
fetch処理中の表示の出し分け
data() { return { post: {} } }, async fetch() { this.post = await this.$http.$get( `${this.api}${this.$route.params.id}` ) },fetchでapi叩いてthis.postに入れるとします。
<template> <p v-if="$fetchState.pending">Loading...</p> <p v-else-if="$fetchState.error">Error: {{ $fetchState.error.message }}</p> <div v-else> <h1>{{post.title}}</h1> <div>{{post.body}}</div> </div> </template>従来のページコンポーネントでは非同期処理が完了してからページ遷移・表示が行われていましたが、今回新しくコンポーネント単位になったことによりクライアントサイドで実行される場合には処理中の表示が発生します。
そこで 「実行中/エラー/実行完了」 の3つの表示を作るわけですが、$fetchStateにはその状態が自動的に入るので、template側ではこのように表示を出し分けることができます。
図
イメージを図にするとこんな感じでしょうか。fetchはmount前(SSR含む)とmethodを叩いたときに呼ばれます。pageComponentではないので、propの値に応じてfetchするようなコンポーネントも作りやすいと思います。
propの値でfetchする例
https://twitter.com/Atinux/status/1106201847734456320?s=20
古いツイートなので$isFetchingとか変数名が異なってますが、propの値を使ってfetchしてSSRする例です(画像2枚目)。
fetchOnServer: false
にすることで一部のコンポーネントはクライアント処理のみにするといったこともできます(画像3枚目)仕組み
async function $fetch() { this.$nuxt.nbFetching++ this.$fetchState.pending = true this.$fetchState.error = null this._hydrated = false let error = null const startTime = Date.now() try { await this.$options.fetch.call(this) } catch (err) { error = normalizeError(err) } const delayLeft = this._fetchDelay - (Date.now() - startTime) if (delayLeft > 0) { await new Promise(resolve => setTimeout(resolve, delayLeft)) } this.$fetchState.error = error this.$fetchState.pending = false this.$fetchState.timestamp = Date.now() this.$nextTick(() => this.$nuxt.nbFetching--) }この辺の処理は上記のコードにある通り、fetchメソッドの実行が完了するまでは
$fetchState.pending
がtrueになり、fetchメソッドでエラー発生した場合には$fetchState.error
にエラーオブジェクトが入るという形になっています。つまり、fetchメソッドの中では敢えてtry catchせずエラーをそのまま投げるように書くことになります。
asyncDataとの違い
これでやっとasyncDataと住み分けができてきた感じです。
現状でfetchに無いのは context です。以前のfetchには引数に渡されていましたが今回の変更で無くなりました。
redirectやresponseのstatusCodeを設定するにはcontextが必要ですが、fetchでは使えないのでしょうか。現状では使えません。そういう処理のためには引き続きasyncDataが必要です。
Nuxt 3: Introducing fetch() hook
Context
fetch hook does not receive any context as 1st argument anymore since it has access to this.The context will be updated to be available through this.\$ctx, this.\$config and this.\$nuxt, learn more on #25
ですがRFCにあるように将来的には this.$ctx が生えるようになるようです。
こちらを使うことでasyncDataの役割はfetchでできるようになっていくと思います。追記: context使えます
https://twitter.com/Atinux/status/1240193656969101312
context、
this.$nuxt.context
で使えました。
- redirectは
this.$nuxt.context.redirect(path)
- resは
process.server
がtrueのときにthis.$nuxt.context.res
に入るので設定できる感じです
- 投稿日:2020-03-18T07:43:47+09:00
爆速でLambda@edgeにNuxt.jsを構築できるテンプレートを作りました
注意事項
Lambda@Edgeに無料利用枠は無いので注意
詳細な利用料金はこちらある日の夜
はぁ・・・やる事無くて暇だしなんかサービス作りたい・・・
とりあえずNuxt.jsでなんか作るか
デプロイ先はどこにしようか、、、Lambda@Edgeにデプロイするの面白そうだなぁ・・・いっちょやってみっか
Serverless Nuxt
ということで作っちゃいました。
成果物はこちら→ serverless-nuxt
不具合修正、機能追加のプルリク待ってます!
あと付けてくれたらめっちゃ喜びます。誰向け?
- サーバー費用ケチりたいけど、ちゃんとしたサービス作りたい人
- とりあえずNuxt/Vue使ってみたい人
- 環境構築めんどくせぇ!!誰かやってくれって人
何が良いの?
- .envをちょろっと弄ってコマンド叩くだけで簡単デプロイ
- Nuxtやる時に大体使うModuleやらPluginやらが導入済み
- デプロイ時にS3に静的ファイルも自動でアップロード!!
- 静的ファイルはCloudFrontを通して取得するから爆速!!
導入済みModule/Plugin
- @nuxt/typescript-build
- @nuxt/typescript-runtime
- @nuxtjs/tailwindcss
- @nuxtjs/dotenv
- @nuxtjs/axios
- @nuxtjs/pwa
- @vue/composition-api
- nuxt-webfontloader
- Stylus
個人的に好きな奴全部ブチ込んでます。
Pugは嫌いなんで入れてないです、使いたい人は自分で入れてどうぞ。ネットワーク図
環境構築
.env編集
AWS_ACCESS_KEY_ID=EXAMPLE_ACCES_KEY AWS_SECRET_ACCESS_KEY=EXAMPLE_SECRET_ACCES_KEY適切な権限が割り振られたユーザーのACCES_KEYを指定する
AWS_DOMAIN=example.comRoute53に登録しているドメインを指定する
Docker構築
$ dcoker-compose build $ docker-compose up -d $ docker-compose exec node ashDockerは使わなくても大丈夫です。
使いたくない人は飛ばしてください。依存ライブラリのインストール
$ npm install
説明要らない気がする開発ビルド
$ npm run dev
Nuxtのビルドを行います。
もちろん開発ビルドなのでファイル変更のWatch, 自動更新も行ってくれます。本番ビルド
$ npm run build $ npm run prod本番とほぼ同じ条件での動作テストが行えます。
ファイル変更のWatch, 自動更新は行いません。AWSへデプロイ
$ npm run build $ npm run deploy下記の処理を上記のコマンドで全て行います。
- CloudFrontのDistributionの設定、Route53との紐付け
- S3バケットの作成、静的ファイルアップロード
- Lambdaの登録、CloudFrontへの紐付け
初回デプロイ時はCloudFrontの設定に時間が掛かるので注意