- 投稿日:2020-02-20T21:52:04+09:00
Laravelでミニブログを作ろう #1
laravelの使い方を一通り習ったので、laravelを使って(競プロの勉強の合間に)ちょこちょこミニブログを作っていくことにします。
作成していく過程で最近学習したAWSだったりCircle CIだったりの復習をしていければと考えてます。
(果たして完成するまでに何ヶ月かかるのか)要件定義
アプリの概要
Markdown記法で記事が書けるミニブログ
主要な機能
- 記事の作成、編集、更新、削除、下書き(ユーザーは複数人登録できる)
- 画像投稿
- タグ付け機能(記事を作成したユーザー以外もタグ付けできる)
- いいね機能
- Markdownエディタ
- レスポンシブデザイン
- 管理人機能(ユーザー一覧、ユーザー詳細表示)
技術要件
- フロント
- Vue.js (いいね機能、タグ付け機能の実装のため)
- Scss
- バックエンド
- php
- laravel
- サーバー
- nginx
- DB
- mysql 5.7(ローカル)
- RDS(AWS)
- インフラ
- AWS
- ECS/ECR
- RDS(mysql)
- EC2
- S3
- VPC
- Route53
- ALB
- ACM
- Terraform(AWSをコード化)
- heroku(多分AWS版のアプリ完成した後、herokuに移行すると思います。お金無いので)
- CircleCI
その他Googleアナリティクスの導入
(非技術要件も定義できれば尚良いんですが...)
作成手順
環境設定(Dockerfile→Circle CI,PHPUnit(テスト),Terraform等)→laravelでアプリの中身を作り上げていく→デプロイ の流れ
laravelのインストール
rootディレクトリに移動してlaravelをインストールします
$ composer create-project laravel/laravel larablog─── laravel(ルートディレクトリ) ├── larablog ・・・今回のアプリ ├── app ├── bootstrap . . .次回からDockerfileを書いていきます
- 投稿日:2020-02-20T21:36:56+09:00
【Vue.Draggable】二列間の移動
ドラッグ&ドロップが実装できるライブラリを使ってみたので、メモです。
前回の記事
この記事の目標
- 項目ドラッグで、リスト間の列移動ができるところまで
目次
環境
Vue.js 2.6.11
Vue.Draggable 2.23.2
1.全体
<template> <div class="draggable"> <div class="d-flex"> <!-- ポケモン --> <div class="col-4"> <h6 class="font-weight-bold">ポケモン</h6> <draggable group="monsters" tag="ul" class="list-group" :list="pokemons"> <li class="list-group-item" v-for="pokemon in pokemons" :key="pokemon.no"> {{ pokemon.name }} </li> </draggable> </div> <!-- デジモン --> <div class="col-4"> <h6 class="font-weight-bold">デジモン</h6> <draggable group="monsters" tag="ul" class="list-group" :list="digimons"> <li class="list-group-item" v-for="digimon in digimons" :key="digimon.no"> {{ digimon.name }} </li> </draggable> </div> </div> </div> </template> <script> import draggable from 'vuedraggable' export default { components: { draggable }, data () { return { pokemons: [ { no: '001', name: 'フシギダネ' }, { no: '004', name: 'ヒトカゲ' }, { no: '007', name: 'ゼニガメ' }, { no: '025', name: 'ピカチュウ' } ], digimons: [ { no: '111', name: 'アグモン' }, { no: '222', name: 'カブテリモン' }, { no: '333', name: 'エンジェウーモン' }, { no: '444', name: 'セントガルゴモン' } ] } } } </script> <style scoped> li { cursor: pointer; } </style>
- ポケモンリストとデジモンリストについて、ドラッグで列間移動できる
2.ポイント
<draggable>
に、group="任意のグループ名"
を付与する同じ名前のグループ同士は、列間の移動ができるようになる
4行目〜
<!-- ポケモン --> <div class="col-4"> <h6 class="font-weight-bold">ポケモン</h6> <draggable group="monsters" tag="ul" class="list-group" :list="pokemons">13行目〜
<!-- デジモン --> <div class="col-4"> <h6 class="font-weight-bold">デジモン</h6> <draggable group="monsters" tag="ul" class="list-group" :list="digimons">↑ ポケモンとデジモンのリストそれぞれに、monstersグループを付与しています
3.参考
- 投稿日:2020-02-20T15:22:38+09:00
Vue.jsのコンポーネントについて
vue.jsを触っていると、インスタンスとコンポーネントとか概念が出てきてごっちゃになりそうだったので、ここではコンポーネントについてまとめます。
コンポーネントとは
同じような処理を行う部分を部品としてまとまった部品
ある部品が、HTML上で、「どのように表示されるのか」をオブジェクトとしてまとめるには、templateオプションを使います。そのtemplateオプションでまとめたオブジェクトに名前(コンポーネントのタグ名)をつけたもの。
index.html<my-component></my-component> <!-- ←ここに部品が表示される -->ちなみに
コンポーネントの命名規則は、
パスカルケース(アッパーキャメル) or ケバブケースだそうです
- パスカル(アッパーキャメル)ケース・・・単語の最初を大文字で始める書き方 (HogeFuga など)
- ケバブケース・・・単語間をハイフンで繋ぐ書き方 (hoge-fuga)
なので上の例では、ケバブケースで書かれてるってことになります
作ったコンポーネントの使い方
- グローバルに登録する方法
- ローカルに登録する方法
がありますが、ローカルに登録する方法を書いていきます。
ローカルに登録してコンポーネントを使えるようにする
Vueインスタンスのcomponentオプションに、「コンポーネントのタグ名:コンポーネントのオブジェクト名」と指定して、このVueインスタンス内で使えるように登録する。
vue.jsvar コンポーネントのオブジェクト名 = { template:'HTML部分' } new Vue({ el:'#app' components:{ 'コンポーネントのタグ名':コンポーネントのオブジェクト名 } })という感じで書きます
<div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div>vue.jsvar MyComponent = {'<p class="my-comp">Hello</p>' } new Vue({ el:'#app', components:{ 'my-component':MyComponent } })Vueインスタンスの「components:」には、「コンポーネントのタグ名:コンポーネントのオブジェクト名」と指定し、「my-component 」というタグ名に「MyComponent」オブジェクトを設定する。
これで、HTML 上に<my-component></my-component>
と書くだけで、作ったコンポーネントが表示されるようになります。
- 投稿日:2020-02-20T15:21:30+09:00
Vue.jsで表示させる方法三種類
表示させるには、3種類ある
- DOMとマスタッシュタグで表示させる方法
- templateプロパティを使って文字列のみでかく
- render関数でかく
例
「こんにちはユーザー名さん」
をブラウザに表示させるために・・・1.普通にテンプレートでかく
index.html<div id="app"> <p>こんにちは</p> <p>{{name}}</p> <p>さん</p> </div>main.jsnew Vue({ el:'#app' data:{ name:'ユーザー名', } })2.templateでかく
以下のような感じで
(基本的には使わないけど)index.html<div id="app1"></div>main.jsvar data = { name:'ユーザー名' } var vm = new Vue ({ el:'#app1', data:data, template:'<p>こんにちは{{name}}さん</p>' })3.render関数でかく
index.html<div id="app"></div>main.jsnew Vue ({ data:{ name:'ユーザー名' }, render:function(createElement){ //第一引数でタグをとる //第二引数で中に入れたいもの(JavaScriptのように) return createElement('h1','こんにちは'+this.name+'さん'); }, }).$mount('#app')↑
createElement
出なくてもh
とかでもなんでも良い
- 投稿日:2020-02-20T15:20:16+09:00
Udemyで学んだVue.jsの仮想DOMの話
- 投稿日:2020-02-20T14:50:45+09:00
【Vue.js】Chromeのデベロッパーツールでデバッグする方法
Vue.js入門 基礎から実践アプリケーション開発まで で、VueRouterの勉強をしていたところ、なぜか値が画面に表示されないエラーが発生。
Vue.js devtoolsではいまいち原因が特定できなかったので、標準でついてるChromeのデベロッパーツールでデバッグしてみた。問題のコードはこちら(トップページ、ユーザー一覧ページの実装は省略)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>SPA</title> </head> <body> <script src="https://unpkg.com/vue@2.5.17"></script> <script src="https://unpkg.com/vue-router@3.0.1"></script> <div id="app"> <router-view></router-view> </div> <script type="text/x-template" id="user-detail"> <div> <div class="loading" v-if="loading">読み込み中...</div> <div v-if="error" class="error"> {{ error }} </div> <div v-if="user"> <h2>{{ user.name }}</h2> <p>{{ user.description }}</p> </div> </div> </script> <script> var userData = [ { id: 1, name: 'hoge', description: 'hogehogehogehoe' }, { id: 2, name: 'wafu', description: 'wafuwafuwafuawefu' } ] var getUser = function (userId, callback) { //userIdを使う setTimeout(function(){ //与えられた callback 関数を配列の各要素に対して一度ずつ呼び出し、callback が true と評価される値を返したすべての要素からなる新しい配列を生成 var filteredUsers = userData.filter(function(user){ return user.id === userId; //検証 }) callback(null, filteredUsers && filteredUsers[0]) //callbackの発動を定義 }, 1000) } var UserDetail = { template: '#user-detail', data: function(){ return{ loading: false, user: null, error: null } }, created: function(){ this.fetchData() }, watch: { '$route': 'fetchData' }, methods: { fetchData: function(){ this.loading = true getUser(this.$route.params.userId, (function(err, user){ //callbackで渡す this.loading = false if(err){ this.err = err.toString }else{ this.user = user } }).bind(this)) } } } var router = new VueRouter({ routes: [ { path: '/users/:userId', component: UserDetail } ] }) var app = new Vue({ router: router }).$mount('#app') </script> </body> </html>
http://127.0.0.1:5500/index.html#/users/1
を打ち込んでも、ずっと 「読み込み中...」 と表示されてしまう。では、早速デバッグしていこう。
cdnを使って、htmlファイル1枚でかいている。
それをそのままchromeに置いてもうまくデバッグできなかったので、Vscodeの右下にあるGo Liveで開く。開けたら、検証=>Sourcesでファイルを選び、行数を選択してブレークポイントを定める。
今回は、getUser関数
に問題がありそうなのでその呼び出しのところにブレークポイントを置いた。ブレークポイントを置いた後、
http://127.0.0.1:5500/index.html#/users/1
にアクセスすると、処理が止まる。そして、変数の部分、今回は
this.$route
の部分にマウスを当てると、変数が保持している値が一目瞭然となる。
this.$route.params.userId
が文字列の "1" であることが分かり、return user.id === userId;
の処理がうまくいっていないことが判明。
return user.id === Number(userId);
とし、無事にエラー解消。Chromeのデベロッパーツール意外と便利!!!
- 投稿日:2020-02-20T12:50:11+09:00
Nuxt.jsで共通stylusを使用できる方法
Nuxt.jsでcssを書くときにデフォルトではSassを使うことが多いと思いますが、
もう一歩踏み込んでStylusでやってみたいと思いました。Stylusとは?
ざっくりStylusの特徴といえば、{}や「 : 」,「 ; 」を使わずにかけることです。
Sassの後発でもあるのでSassの書き方も使えるみたいです。(どこまでかは今お試し中です。)
ソースをコピペするときはそのまま使えたりするので便利ですよね。Stylusを使えるようにする
ますは必要なモジュールを入れます。
$ yarn add stylus stylus-loadervueファイルのstyleタグにlang設定します。
<style lang="stylus"> .section color red font-size 1.6rem border 1px solid #000000 .innner-section padding 2em </style>サイトで共通の変数やclassを使いたい
vueファイル内であれば下記のような書き方で変数を使えます。
<style lang="stylus"> $red #ff0000 .section color $red font-size 1.6rem border 1px solid $red </style>しかし、別のvueファイルでの変数は使えません。
共通用のファイルを作成する必要があります。assets -variables.scssこのままだSassのままなので下記のコマンドを叩き、追加してください。
$yarn add @nuxtjs/style-resourcesさらに下記にファイル構成を変更(こんな感じのほうがまとまりがいいと思います。)
assets -stylus -_variables.styl先ほど作成したファイルに変数などをまとめます。
assets/stylus/_variables.styl$white = #ffffff $black = #000000 $display01 = 600pxnuxt.config.jsの設定を行います。
nuxt.config.jsexport default { // 中略 modules: [ '@nuxtjs/style-resources' ], styleResources: { stylus: [ '~/assets/stylus/_variables.styl' ] } }これで各vueファイルに変数の使用や共通styleを使うことができます。
- 投稿日:2020-02-20T10:00:33+09:00
vue.jsのfilterをthisから呼び出す
テキストを変換する処理を切り分けられるので可読性も上がって便利なfilter。
公式 (https://jp.vuejs.org/v2/guide/filters.html) では{{ message | capitalize }} <div v-bind:id="rawId | formatId"></div>のmustache展開とv-bind式の二種のみの使い方しか紹介していない。
実はmethod内等から呼び出して使いたい場合はthis.$options.filters.capitalize(this.message) this.$options.filters.formatId(this.rawId)のように
this.$options.filters
から呼び出せる。
nuxtjsだとhead()内などで呼び出したいこともあると思う。意外と日本語で記載している記事を見かけなかったので一応メモ。