Vue.jsを再入門する 4
前回記事
今回は編集機能と削除機能を実装します。
モーダルを発生させる
ボタンの設置
タスクの横にボタンを置き、押下時にモーダルが発生するようにします。
b-checkbox
の後ろに
<button class="button is-primary" v-on:click="editTask()">Edit</button>
を記述します。
モーダルの設置
モーダルを発生させるにはb-modal
を使用します。
<b-modal :active.sync="isModalActive" has-modal-card> </b-modal>
has-modal-card
を設定するとその中に設定したモーダルの中身がモバイルでも崩れずに見れるらしいです。とりあえず設定しておきます。
:active.sync
でモーダルをON/OFFします。
トリガーとなるisModalActive
はdata内に定義します。
data() { return { taskText: '', tasks: [], isModalActive: false } }
タスクの編集
editTask()
の実装をします。
この関数が呼ばれたらisModalActive
をtrue
にします。
editTask() { this.isModalActive = true }
これでモーダルが発生するようになりました!
実際に確認します。
モーダルの上にフォームを作る
今回は別Componentとして作っていきたいと思います。
ファイル作成
src/components
配下にEditModal.vue
というファイルを作ります。
Buefyのモーダルサンプルを見よう見まねでフォームを作ります。
<form action=""> <div class="modal-card" style="width: auto"> <header class="modal-card-head"> <p class="modal-card-title">Edit</p> </header> <section class="modal-card-body"> <b-field label="Task"> <b-input type="task" :value="task" placeholder="タスクを入力してください" required> </b-input> </b-field> </section> <footer class="modal-card-foot"> <button class="button" type="button">削除</button> <button class="button is-primary">完了</button> </footer> </div> </form>
modal-card
の詳細仕様がどこに書いてあるのか不明なのでサンプルを見ながら解説していきます。
modal-card
以下にはmodal-card-head
とmodal-card-body
、modal-card-foot
があります。
Modal Card API
modal-card-head
下の画像の上段のLogin
の部分がmodal-card-head
です。
modal-card-body
次にフォームが並んでいる中段がmodal-card-body
です。
modal-card-foot
ボタンが並んでいる下段がmodal-card-foot
です。
中には通常通りのhtmlを書いていきます。
見た目はこれで完了です。
削除ボタンを押下時の呼び出す関数をdeleteTask()
、完了ボタンを押下時に呼び出す関数をeditedTask()
とします。
コンポーネントを読み込む
親コンポーネント(ここではToDo.vue
)内で作成したコンポーネント(ここではEditModal
)を読み込みます。
<script>
内に
import EditModal from '@/components/EditModal'
と記述し、コンポーネントを読み込みます。
@
はsrcまでのパスです。
そしてexport default {
以下に
components: { 'edit-modal': EditModal },
を記述することで、コンポーネント内で<edit-modal>
タグとして扱うことができます。
最後にb-modal
以下にedit-modal
を記述し、見た目の完成です。
<b-modal :active.sync="isModalActive"> <edit-modal></edit-modal> </b-modal>
実際にこうなります。
親子の連携
以上で見た目は完了しましたが、実際に値が移動していません。
親コンポーネントから値の送信、子コンポーネントでの値の当て込み、子コンポーネントから親コンポーネントの関数実行まで一気にやります。
親から子へ
親コンポーネントから子コンポーネントへ値を渡すために子コンポーネントにpropsを設定します。
今回は配列のindexとtaskが
export default {
以下にこちらを追記します。
props: { 'task': String },
そして親コンポーネントに送るための値を設定し、v-bind
で子コンポーネントに値を渡します。
今回はformProps
という名前でモデルを用意しました。
<b-modal :active.sync="isModalActive"> <edit-modal v-bind="formProps" ></edit-modal> </b-modal>
formProps: { task: '' }
次にeditTask()
を修正し、editTask呼び出し時に編集対象のTaskの文字をeditingText
に代入するようにします。
editTask(task, index) { this.formProps.task = task this.isModalActive = true },
モーダルを発生させるボタンは以下のようにします。
<button class="button is-primary" v-on:click="editTask(task.message)">Edit</button>
これで親から子への送信は完了です。
子コンポーネントでの値の当て込み
次に受け取った値をモーダル内のテキストフィールドに入るようにします。
data
内にtaskText
を記述し、初期値としてpropsで受け取ったtask
を代入します。
data() { return { taskText: this.task } },
そして前回と同様にb-input
にv-model="taskText"
を設定するとモーダル発生時にテキストフィールドにtaskTextの値が入って表示されます。
この時点で実行すると、以下のようになります。
これで完了です
子から親の関数実行
次に子から親の関数を実行します。
これはカスタムイベントハンドラーを使用して実現します。
v-on
を使用してイベントを購読します。
<b-modal :active.sync="isModalActive"> <edit-modal v-bind="formProps" v-on:edited="editedTask" v-on:delete="deleteTask"></edit-modal> </b-modal>
edited
というイベントが発火した時にeditedTask
が実行され、delete
が発火した時にdeleteTask
を実行します。
editedTask
とdeleteTask
は一旦モーダルを消す実装のみをします。
editedTask() { this.isModalActive = false }, deleteTask() { this.isModalActive = false }
次に子にて、ボタンを押下された際に親のイベントを発火するようにします。
まずmodal-foot
内のボタンにv-on:click
を記述します。
<footer class="modal-card-foot"> <button class="button" type="button" v-on:click="deleteTaskChild()">削除</button> <button class="button is-primary" v-on:click="editedTaskChild()">完了</button> </footer>
次にdeleteTaskChild
、editedTaskChild
を実装します。
editedTask() { this.$emit('edited') }, deleteTask() { this.$emit('delete') }
$emit
を使用することで親で購読しているイベントを発火することができます。
実行してみます。
モーダルを消すことに成功しました。
削除を実装する。
次に削除の関数を実装します。
現在tasks
という配列を持っていますが、編集時のindexが判断できないため、editingIndex
をdata
内に宣言します。
次にリスト描画時のv-for
でindex
を取得するように追記します。
<div class="field task-field" v-for="(task, index) in tasks" v-bind:data="task" v-bind:key="task.text">
次にeditTask
関数内でeditingIndex
にindex
を代入するように追記します。
editTask(task, index) { this.formProps.task = task this.editingIndex = index this.isModalActive = true },
次に編集ボタンが呼び出すeditTask
の引数にindexを追加します
<button class="button is-primary" v-on:click="editTask(task.message, index)">Edit</button>
最後にdeleteTask
を実装して終わりです。
編集中のIndexの場所にあるtasks
内の要素を削除し、保存します。
deleteTask() { this.tasks.splice(this.editingIndex, 1) this.storeTasks() this.isModalActive = false }
これで削除機能が実装できました。
実行してみます。
削除ができました!
編集を実装する
編集機能の実装をします。
編集中の文字列は子がtaskText
という変数で持っているのでこれを親に渡します。
$emit
内で値を渡すには、this.$emit('イベント名', 値)
という風にします。
今回は親にtaskText
を渡すのみなので以下のようになります。
editedTaskChild() { this.$emit('edited', this.taskText) },
親のeditedTask()
は引数をもつようにeditedTask(task)
とします。
最後に、編集後のjson配列、置き換え、保存をしています。
editedTask(task) { var editedData = { message : task, done: this.tasks[this.editingIndex].done} this.tasks[this.editingIndex] = editedData this.storeTasks() this.isModalActive = false },
これで全部の機能が揃いました。
実行してみます。
再入門をして
Vue.jsの色々な機能を使用してみました。
まだまだ他にも色々な機能があり使いきれてはいないですが、今後も色々触っていきたいと思います。
今後、vuexも触っていきます。
Vue.jsを再入門する 3
前回記事
今回はLocalStorageを使用し、データの永続化を実装します。
LocalStorageとは
HTML5から導入されたWebStorage APIです。
ブラウザに組み込まれたデータベースと言うとわかりやすいかもしれません。
今回はToDoの一覧を永続的に保存したいけどサーバーまで実装する必要ないと言うことで使って行きたいと思います。
vue-ls
Vue.jsでLocalStorageを楽に使用するためにvue-lsというプラグインを使用します。
npm install vue-ls
でインストール後、main.js
内に
import VueLocalStorage from 'vue-ls' Vue.use(VueLocalStorage)
と記述し使用します。
保存する
localStorage.setItem('task', JSON.stringify(this.tasks))
これだけで実装終わりです。
セットする
このままだと再読み込みなどをしたときに表示されません。
export default
内に mounted()を定義し、読み込み時の動作を指定します。
今回は取得して表示するだけなので以下のようになります。
mounted() { this.tasks = JSON.parse(localStorage.getItem('tasks')) || [] },
完了時もセットする
完了時にも保存します。
考え方的にはtasks
を常に監視して、変更があった場合保存するようにします。
ここでwatch
を使用します。
今回はオブジェクト内にネストされた値の変更を検知するために上リンクのcのパターンを利用します。
watch: { tasks: { handler: function(){ this.storeTasks() }, deep: true, } },
これで完了時にも保存されます。
このあとに実装する編集後にも保存されるのでこのwatch
はとても便利ですね。
実際に動作を見てみましょう。
入力 → 完了 → リロードをしてみます。
(リロードがとてもわかりづらいですが、カクッとなってる時がリロード時です)
次回
次回は編集・削除機能をつけてこのシリーズを終わらせたいと思います。
Vue.jsを再入門する 2
前回記事
設計
どんなアプリにするか簡易的な設計書を書きます。
前回定めた機能を満たすように作ります。
レスポンシブ対応がしやすいようにこのような形にしました。
機能一覧
追加
追加機能はアプリケーション上段で行います。
入力し、+ボタン押下で追加します。
完了
完了機能はタスクセルの左側にある○を押下することで実現します。
今回完了を取り消す行為は仕様の範囲外としますが、気が向いたら実装します。
編集・削除
編集・削除機能はタスクセルの右側にあるペンを押下することで実現します。
ダイアログが発生し、テキストの編集ができます。
削除する場合は左下のボタン、完了する場合は編集後に右側のボタンを押下します。
テキストを全部削除した状態で完了を押した場合は削除します。
開発開始
今回、CSSフレームワークはBuefyを使ってみたいと思います。
過去にbootstrap-vueを使用していましたが、今回はお試しということで。
npm install buefy
を実行し、完了後 src/main.js
に以下を追記します。
import Buefy from 'buefy' import 'buefy/lib/buefy.css' Vue.use(Buefy)
ベースを作る
アプリケーションのベースとなる部分を作ります。
components
ディレクトリ以下に ToDo.vue
というファイルを作成します。
中身は以下のようにします。
<template> <div class="todo"> </div> </template> <script> export default { name: 'ToDo' } </script> <style scoped> </style>
<div class="todo"></div>
内にHTMLを書いていきます。
入出力パーツを設置する
タスクを入力するパーツ、出力するパーツ(+チェックボックス)をコンポーネント内に設置します。
Buefyのドキュメントを読みながら実際に使うパーツを選定します。
入力はb-input
、出力はb-checkbox
をv-for
でタスク分出力します。
コードは以下の通りです。
<b-input minlength="1" maxlength="30" placeholder="タスクを入力してください"></b-input> <p class="control"> <button class="button is-primary" v-on:click="addTodo()">+</button> </p> </b-field> <section> <div class="field" v-for="task in tasks" v-bind:data="task" v-bind:key="task.text"> <b-checkbox> {{ task.message }} </b-checkbox> </div> </section>
data
内にtasksを定義し、出力確認用に二個くらい入れておきます。
export default { name: 'ToDo', data() { return { tasks: [ { message: 'タスク1' }, { message: 'タスク2' } ] } } }
この状態でhttp://localhost:8080
にアクセスし、以下のように表示されたらOKです。
タスク追加機能
タスクを追加する機能を実装します。
イメージとしては
- バインディングするmodelを作る
input
タグにv-model
を設定addTask
メソッドを実装するbutton
タグにv-on:click="addTask()"
でメソッドを呼び出す
です。
まずはバインディングするmodelをdata
内に定義します。
変数名はtaskTextとします。
data() { return { taskText: '', tasks: [ { message: 'タスク1' }, { message: 'タスク2' } ] } }
次にinput
タグにv-model
を設定します。
v-model
はバインディングのために使用します。
こうすることでinput
タグ内で入力された値がリアルタイムでtaskText
内に代入されます。
input
タグの部分は以下のようになります
<b-input v-model="taskText" minlength="1" maxlength="30" placeholder="タスクを入力してください"></b-input>
次にタスクを追加するメソッドを実装します。
json文字列を定義し、tasks
に追加します。
最後にtaskTextを空文字にするとinput
タグ内の入力文字も消えます。
実装は以下のようになります。
methods: { addTask() { var addData = { message : this.taskText } this.tasks.push(addData) this.taskText = '' } }
最後にbutton
タグにv-on:click
を設定し、押下時にaddTask
が呼び出されるようにします。
<button class="button is-primary" v-on:click="addTask()">+</button>
これでタスクの追加機能の実装は一旦終わりです。
実際に動かしてみると以下のようになります
これで入出力のパーツの設置が終了しました。
タスクを完了にする。
次にタスクを完了する処理を実装していきます。
以下のような構想で作ります
- tasksのデータモデルにdoneを追加し、それぞれのタスクを判断できるようにする
b-checkbox
にv-model
を設定し、task.done
がtrue<->falseで書き換わるようにする- doneになったときのcssを書く
- doneになったときに、テキストに
class=done
をv-bind
で設定する
まず、tasksのデータモデルにdoneを追加します。
addTask
を以下のように修正します。
addTask() { var addData = { message : this.taskText, done: false } this.tasks.push(addData) this.taskText = '' }
次にb-checkbocx
にv-model
を設定します。
<b-checkbox v-model="task.done">
これでtask.doneが動的に変更されます。
次にdoneになったときのcssを書きましょう。 styleタグ内に以下のcssを書きます。
.done { text-decoration: line-through; color: grey; }
これでdoneになったときに打ち消し線がつき、テキストの色が灰色になるようになりました。
最後にタスクのテキストにv-bind
するようにします。
現在のままだとテキストがタグで囲まれていないのでspan
タグをつけ、そこにv-bind
します。
<span v-bind:class="{'done': task.done}"> {{ task.message }} </span>
これでチェックボックスが操作されたときにタスクの完了/未完了が変更されるようになりました。
実際に動作確認してみましょう。
以上でタスクを完了する実装の終了です。
次回
次回はタスク一覧をlocal storageに保存するようにします。
時間があったら番外編でcssをいじっていこうと思います。
余談
iPadでメモを取るときにこのアプリを使用しています。
ノートがこれ一冊で完結できて、手書きの温もりの残るのでとてもおすすめです!
(なぜかiPadから画像書き出ししても白紙なのでスクショで書き出してます…)
Vue.jsを再入門する 1
Vue.js
なぜ再入門?
仕事で業務システムのUI側をメインに開発した経験はあるけれども、詳しいところまで調査せずに使ってました。
これを気に色々と調べてもっとまともに使っていけるようになればと思います。
作るもの
ToDoアプリを作ります。
(だいたいToDoアプリを入門で作るので)
Project 作成
vue-cliを使ってプロジェクトを作成します。(リンク参照)
作成し終わったら npm run dev
を実行して起動。
ブラウザから http://localhost:8080/#/
へアクセスし、
このようなページが表示されたら完了です。
開発は src
ディレクトリの中でしていきます。
プロジェクト生成後の構成は以下の通りです。
assets
assets
ディレクトリ内はアプリケーションに組み込む画像などの素材ファイルを入れます。
components
components
ディレクトリ内はコンポーネントとして作成したファイルを入れます。
拡張子は .vue
を使用します。
router
router/index.js
はルーティングと表示するコンポーネントを定義しています。
App.vue
アプリケーションとなる部分となります。
main.js
Vueインスタンスを作成し、App.vueと紐づけています。
ToDoアプリ
ToDoアプリの仕様を決めます。
機能一覧
以下が機能です。
機能名 | 概要 |
---|---|
追加 | ToDoの追加ができる。 |
削除 | ToDoの削除ができる。 |
完了 | ToDoの完了ができる。 |
編集 | ToDoの編集ができる。 |
すごいシンプルなToDoアプリを作ります。
UI
特にここには拘らず、ただのリストを作っていきます。
サーバー
今回はモックでやりますが気が向いたらサーバー側も書いていきたいと思います。
最近興味があるGoとかで書きたいなあ・・・
次回
準備が完了したので今回はここまでにします。
次回から実際にToDoアプリを作りながらVueの色々なところを深く探っていけたらと思います。
一週間カリブ海一周旅行をして必須だったものコレクション
カリブ海とは
ココらへん。
行ったところは、マイアミ → ジャマイカ → コズメル (メキシコ) → コスタマヤ (メキシコ) です。
クルーズで行ったので備忘録も含め書きます。
必要なもの
圧縮袋
確実に服だけで荷物がパンパンになります。
服は圧縮して持っていきましょう。
これが一番オススメの圧縮袋です。
Vacplus 衣類圧縮袋【10枚セット 掃除機不要 終身交換承り】 手巻き 圧縮袋 防塵防湿 衣類真空パック ダニ、カビ対策 省スペース?旅行 旅行用 (50x35cmx5枚&40x30cmx5枚)
- 出版社/メーカー: Vacplus
- メディア: ホーム&キッチン
- この商品を含むブログを見る
チャックを簡単に締めるスライダーがついていて、簡単に締めることができます。
また、チャックの力も強いので空気を抜くときや、運搬中に開くことはありません。
ウェストポーチ
パスポートを守るバッグです。
今まで、確実に守るためウェストポーチをつけて服の中に隠して行動してました。
この方法が一番安全と思います。
自分の場合はこれを持っていて、中にクレジットカード、現金、スマホ、船のカードを入れて行動してました。
日焼け止め
めちゃくちゃ日差しが強いので日焼け止めは必須です。
痛いくらい強いです。
スキンアクア サラフィットUVさらさらエッセンス 無香料 (SPF50+ PA++++) 80g
- 出版社/メーカー: ロート製薬
- 発売日: 2016/02/16
- メディア: ヘルスケア&ケア用品
- この商品を含むブログを見る
運動着
これは自分がクルーズで旅をしたから特殊かもしれませんが、運動着が必須です。 船内にはジムがあり、毎日運動して汗を流します。 一番のおすすめのコスパがいいのはこれです。
アクティビティに参加する場合は持っていて損は無いです。
水着
どこに行っても海です。
アクティビティも水に入るものが多いので絶対に水着を持っていきましょう。
冬 (2月) でも余裕で海に入れます。
現金
どこも米ドルで決済できました。
レストランはクレジットカードで大丈夫ですが、露天などでは現金しか受け付けないので現金を持っていきましょう。
最後に
冬のカリブ海は避寒になってとても良いです!
現地には大量のボッタクリがいるので気をつけながら買い物をしましょう。
基本的に、もうお金使い切っちゃったよ!って言うとスルーされます。
マネージャーとしてTeam Geakを読んだ
Team Geek ―Googleのギークたちはいかにしてチームを作るのか
- 作者: Brian W. Fitzpatrick,Ben Collins-Sussman,及川卓也,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/07/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (21件) を見る
過去に一度読みましたが、マネージャーになってからもう一度目を通そうと思い、再読しました。
「はじめに」の「対象読者」に書いてありますが、「マネジメント」する人は対象読者ではありません。
しかし内容はマネジメントをする人にとっても重要なことが多く書かれているので読むことを推奨します。
良いなと思う部分をかいつまんで紹介します。
HRT
1章内で何度も書かれている「謙虚・尊敬・信頼」です。
この章では、チームで成功するには「謙虚・尊敬・信頼」の3つが大切だということを伝えています。
マイケル・ジョーダンや様々な名誉あるエンジニアを例に出し、一人では超人的な偉業を達成できるわけではない。としています。
むしろ「一人で仕事するほうがリスクが高い」と。
チーム開発がすべてで、「ソフトウェア開発はチームスポーツである。」と例えています。
そしてその「チーム」で働くときに3つのポイントがあると言います。
それが「謙虚・尊敬・信頼」です。
HRTとはそれぞれの頭文字です。
謙虚 = Humility
尊敬 = Respect
信頼 = Trust
2章ではこのHRTを使ったチームづくりについて書いてあるので是非読んでみてください!
リーダーシップパターン
本書は「マネジメント」をする人は対象ではないとしていますが、3章はエンジニアチームをマネジメントする人には重要な章となります。
特に本書が重要だと伝えたいのは エゴをなくす
ということです。
その エゴをなくす
方法も幾つか紹介されています。
解雇されるのを待とう。
これは個人的に面白いなと思いました。 5章の 5.5 プランB:逃げる の章で書かれているものです。
Googleの新しい従業員からどうすれば仕事をうまくやれるのかとよく聞かれる。私は半分冗談でこう答えている。簡単なことだ。私はGoogleと世界にとって「正しいこと」をしている。あとは座って解雇されるのを待つだけだ。解雇されなければ、「正しいこと」ができたことになる。解雇されたら雇用主を間違えたのだ。いずれにしても私は正しいことをしている。これが私のキャリア戦略だ。
この気持ちで働けば解雇されない限りうまく仕事をしているって気持ちになれますねw
4月以降からiOSアプリを審査にiPhone Xの対応が必要に
タイトルの通りです。
Submitting iOS apps to the App Store - Apple Developer
Update your app for iPhone X. Test your apps to make sure they are ready to take advantage of the Super Retina display by respecting safe areas, supporting adaptive layouts, and more. Find and address UI issues in your app before testing on a device to make sure your app looks great on iPhone X.
翻訳すると、
iPhone Xに対応したアプリのアップデートが必要です。Safe Areaを考慮し、アダプティブレイアウトに対応するなど、Super Retinaディスプレイを最大限に活かしましょう。デバイスでテストする前にUIの問題点を見つけて解決し、iPhoneX上で良い見た目のアプリにしましょう。
iPhone X流行らないと思ってそこまで対応しなくていいかなと思ってましたが・・・
こちらは日本語で書かれているiPhone Xに対応するためのページです。
iPhone X用にアプリケーションをアップデートする - iOS - Apple Developer