主夫ときどきプログラマ

プログラミング、Webエンジニアリング、etc

「本書けますよ」を具体的に考えた結果「連載の仕事を取りに行け」という結論に至った

f:id:masayuki14:20180518093625j:plain

連載の仕事をください。小さくてもいいので。

きっかけ

はんなりPython#5の懇親会で「本書けますよ」ってなことを言われた。(コミュニティに参加することで見えてくるもの - 主夫ときどきプログラマ

「いやいや、そんなのむりですよ。」であったり「そうですね、書いちゃいましょうか。」みたいなことを社交辞令のように話して、普通はその場限りの話題になるだろう。

でも「本書けますよ」なんてのは自分の発想に無いところからの意見だったので、具体的に考えてみた。

本の種類

本といってもいろいろ種類がある。 エンジニアなので技術書っていうのが1番憧れるところではある。 たとえばRubyist伊藤さんプロを目指す人のためのRuby入門を出版している。(Ruby界隈の有名人) でも自分には技術書を出版できるほど精通した分野なんて無いし、実績もないので無理だ。

次に思い浮かぶのが新書でありそうな「フリーランスになる方法」のようなもの。 これもフリーランスをやっていてこそのノウハウなんかを書くんだろうけど、 そもそもフリーランスになりたくてなったわけではないし、 いままで自分がフリーランスであるということを体系的に考えたことがないのでこれも無理そう。

そこで目についたのが「エッセイ集」。これならできるかもしれない。ということで手元にあるエッセイ集のような本を調べることにした。

エッセイ集を分析する

手元にあるエッセイ集をいくつか並べた。

これらは本を書くために描き下ろしたエッセイが集められているのではなく、ブログや雑誌で書かれたものを集めたものになっている。 なので「本を書くぞ!!」っていうモチベーションは不要で、「1つ1つの記事を丁寧に書こう」というモチベーションで続けられそうだ。

ブログで1つ1つの記事を積み上げていけば何とかなるかもしれない。

書籍としての一貫性

Joel on Softwareであればソフトウェア開発について、社会人大学人見知り学部 卒業見込であれば芸人らしくオチのある文章、開店休業であれば食に関するエッセイという具合に書籍には一貫性がある。

自分がエッセイを書く場合も一貫性を持たせたほうが良さそうだ。とりわけ働き方改革なんて言葉が世間を賑わせているのでフリーランスのライフスタイル、ワークスタイルをテーマにするのがいいかもしれない。

エッセイの数は30〜40本

それぞれの本にはエッセイの他に、まえがき、あとがきがあったり書き下ろしの文章があったりするが、 メインであるエッセイは30〜40本ある。月刊連載とすると約3年分の仕事がまとめられていることになる。

同じようなペースでエッセイを書いていくと最低3年はブログを続ける必要があるし、その時々の渾身の文章を書かないといけない。 継続することは大事なのだ。

1つのエッセイあたりの文字数は2000字前後

Joel on Software 以外の本はどれも雑誌の連載をまとめたものになっている。 本によって多少異なるけれど、どのエッセイも3ページほどで同じような文章量だ。 ざっと数えたところ2000字前後で1つのエッセイになっている。

子供の頃は原稿用紙5枚の作文なんて苦行でしかなかったけど、今ならいけそうな気がする。

文章とセットの写真やイラスト

雑誌連載というのも関係しそうだが、それぞれのエッセイには必ず写真やイラストが一緒に載せられている。 イラストはおそらく作家の直筆だろう。写真は風景が多かった。

イラストを書くことに関しては可もなく不可もなく、という程度だが、PCに取り込んで加工するスキルが無いのでまずは写真ではじめるのが無難そうだ。 そのうち直筆のイラストにしていきたい。イラストのほうが人間味がでそうじゃん!!

作家のユニーク性

各作家はそれぞれの分野の一流であるし、ユニークであったりする。そして長く活躍している。 そういう人物には必ず固定のファンがいるもので、自分もこれら作家のファンであると言える。

自分はエンジニアとして一流ってわけではないけど、ユニーク性っていう部分に絞れば悪くないと思う。 だって主夫でフリーランスでコミュニティのオーガナイザーなんだぜ!! そしてユニーク性をアピールしてファンを作っていく必要もありそうだ。

まとめ

まとめると

  • 記事に一貫性をもたせる
  • エッセイ数は30〜40本
  • 1エッセイあたり2000字
  • 写真やイラストとセットにする
  • ユニーク性を演出する

を実現できえれば、本を作る上での最低限の体裁は整いそうだ。

実現するには

2000字程度のエッセイを30本書く必要がある。 毎月1本書いたとして2年半かかる計算だ。これが最低条件。 一番手軽なのはブログでエッセイを書くことだ。

しかし、文章を書くことを仕事にしたことがない人間が、はたして良い文章など書けるのだろうか。 今まで意識してエッセイを書いたこと無いが、そもそもエッセイとは何なのだ?

リングに上がろう

ブログは趣味の延長でしか無いし、そこに責任は発生しない。 文章を書いてそれを評価してもらいお金をもらう、というリングに立たないといけない。 仕事として文章を書くことで責任も生まれるし、その厳しさにさらされる。

文章のプロでない以上、まずはプロになるためのリングに上がらないといけないだろう。 それで読者、編集者にボコボコにされることで、やっと「本書けますよ」を真に受けられるんじゃないだろうか。 そのためには知り合いのツテを辿ってでも自分から仕事を取りに行かないといけない。

私をリングに上げてください。

これからのこと

  • 毎月1本、渾身のフリーランスエッセイをブログで書く(2000字)
  • 小さくていいので文章を書く仕事を取りに行く

の2本立てで行動しようと思う。そうすれば、3年後に本が出版出来るはずだ。

MySQL InnoDB Clusterを動かしてみた成果を発表してきた

MySQL InnoDB Cluster を使って運用を手抜きしようというタイトルでテクテクTech #2で発表してきました。MySQL InnoDB Cluster は先月Oracle主催のセミナーで初めて知って気になったので、その時のセミナー資料をみながら実際に動かしてみました。

masayuki14.hatenablog.com

発表ではMySQL InnoDB Cluster の概要を説明してからデモをやって、実際の動きをみなさんに見てもらいました。デモ自体はわりとスムーズにできましたが予想以上に時間がかかってしまい、発表時間25分のところを40分もかかってしまいました。デモをやるのは時間かかりますね。

speakerdeck.com

懇親会でフリーランス集めて仕事のやり方や1日の過ごし方を発表する会をしたいね、という話になったので次はその時にでも発表しようと思います。

コミュニティに参加することで見えてくるもの

f:id:masayuki14:20180502113511j:plain

はんなりPython#5の懇親会にて。

主催者ということで、コミュニティの説明をしたり発表したりで毎回人前にたっている。 自己紹介は「主夫」業がメインで、パートタイムでエンジニア(フリーランス)してます、という流れ。 少しずつ認知されてきた感じがする。

今回の懇親会でそういう自分の経歴を話す機会があった。

視点が変わると見えるものが変わる

務めていた会社が解散になって、他の会社をいろいろ見てみたいからと言う理由で そのままフリーランスになって、 結婚して子供がいて妻がフルタイムで働いているから自分が家事全般して、 空いた時間の制約の中でソフトウェア開発をするようになって、 子供も大きくなっってきて余裕が出来てきたからコミュニティ始めて、 っていうことをざっくりと話した。

すると意外な反応があった。

主夫でフリーランスでコミュニティをオーガナイズしてる人なんて他にいないよ。
本書けるよ。ロールモデルとして目指す人いそう。
などなど。

自分のような仕事や生活の仕方をしてる人は珍しいだろう、 ということに自覚はあったけど、 改めて他の人から言われることでそれを再認識した。

そして、そういうこと知りたいと思う人がいるということ。

フリーランスだから出来る話があるらしい

ということで、これまでは技術系の内容をブログに書いていたけど これからはライフスタイル的なものもブログに書いていこうと思う。

ユーチューバーなりましょう、という話もあったけどそれはどうなんでしょうね。

MySQLのイベントにいってきた

f:id:masayuki14:20180412180431p:plain

MySQL InnoDB Cluster入門 ※大阪開催 に参加してきた。

最近はアプリケーションからDBとしてMySQLを使う程度で インフラとしてのMySQLの利用から遠ざかっていた。 最近のMySQLの事情をキャッチアップするために参加してきた。

内容は MySQL InnoDB Cluster の概要と、構成方法、最後にデモを見せてくれた。 セミナーの資料も公開されている。 セミナー資料

参加者が7名と少なかったけど、内容はかなり充実していた。MySQL使っている人は行ったほうがいいと思う。 今まで知らなかったけど結構セミナーをやっているようなので今後はフォローしていきたい。 主催者の@yyamasaki1さんがイベント管理をしている模様。

MySQL InnoDB Cluster とは

の3つのコンポーネントを組み合わせて作るMySQLの高可用性構成。 それぞれは単体で利用できるコンポーネントで、これらを組み合わせることで自動フェイルオーバーを含む信頼性の高いDBインフラを構築できる。

今回知ったキーワード

MySQL Group Replication

複数台のサーバーがグループを作って、お互いに通信しあいながらレプリケーションを行う。 グループのメンバー管理と障害検知が自動化されている。 マスタとなっているサーバーに障害が発生した時、自動的に他のサーバーが次のマスタに昇格する。 シングルマスターで運用できるけど、マルチマスタでの構成も容易。

MySQL Router

複数のMySQLサーバーへの接続を振り分けてくれる。そのまんまルーター。 R/Oの複数台のサーバーを登録するとラウンドロビンで接続を振り分けてくれる。 負荷分散としても利用できる。 MySQL Group Replication と合わせて使う時、マスタサーバーが変わった時でも自動で追随してくれる。 アプリケーションはマスタがどのサーバーかを意識する必要がなくなる。

Mysql Shell

MySQLサーバー管理用のCLIツール。JavascriptPythonSQLで管理コードが書ける。 MySQL Group Replicationで使う場合のサーバー設定を自動でうやってくれたり(my.confの設定など) MySQL Routerの設定、管理もできる。 バッチ処理によるサーバー管理処理も自動化できちゃう。すごく良さそう。

マルチスレッドスレーブ

スレーブ側のSQLスレッド(リレーログを実行してデータを更新するスレッド)がマルチスレッドになっている。 MySQL5.7から同一スキーマ、同一テーブルでもマルチスレッドで更新できるようになっていて、MySQL Group Replicationでもサポートしてる。

スプリットブレイン

一般的なクラスタシステムで、それぞれのノードはうまく動いているのにお互いの通信だけがうまくいかない状態。 どちらも正常に更新できてしまうので、同期が復旧した時に競合が発生してしまう。 その回避のために、スプリットブレインが発生したらどちらかを落とすのが通常の解決策。 多数決で生存数の少ないグループに所属する方を落とす。その場合奇数の方がいい。 マルチマスタでMySQL InnoDB Clusterを構成する時に発生する。

次のステップ

改めて認識したけど、どうも自分はDataBaseってやつがけっこう好きらしい。 今回の資料にはチュートリアルが紹介されているので自分でも動かしてみよう。 その成果をブログに書いたり勉強会で発表できればいいかな。

次回のイベント

次回は5月25日に大阪で大きめのMySQLにイベントを企画しているようだ。 MySQLの開発者もアメリカからやって来てお弁当もついてくる大きめのイベントになるそう。 MySQL8のリリースは公式アナウンスはないけど、つまり、察するに・・・。

2018年の目標

今年も四半期が過ぎようとしているけれど、ちゃんと目標というか抱負を示そうと思います。 目標を立てるようになって今年で3年目。
なんだかんだ遅くなってもこうやってアウトプットする僕ってえらいですよね。

コミュニティ活動

去年始めた2つのコミュニティ活動を今年も継続する。そしてRuby界隈にも参加する。

OSS Gateは今年も3回はWorkshopをやるということと、京都で仲間を作るのが目標。
会場の協力をしてくれるような人が現れたら嬉しい。

はんなりPythonは毎月やっているのでなるべく多く発表をしようと思う。
始めは毎回やろうと思っていたけど、参加者目線で考えると 毎回同じ人が発表するのはどうなんだろだろう、っていうのと、 他にも発表してくれる人が増えて欲しい、 ということで毎回の発表は控える。

Ruby界隈でいうとKyoto.rbで1回は発表しよう。

OSS開発

去年は微力ながらもOSS開発に参加したので今年も微力ながら参加しますよ!!
でもできれば回数を増やしたいし、コードにもコミットしたい。
Red Data Toolsの開発が始まったばかりでちょっと気になるので飛び込んでみようかな。

ブログ/Qiita

これも継続案件で月1ペースで何かしらのアウトプットを続けていく。

本を読み返す

去年はSoftwareDesignを年間購読していたんだけど、雑誌を読む習慣がつく反面、時間的に他の本を読むことが難しくなってしまった。 今年は新しい技術書はもちろんだけど、蔵書を読み返すようにする。

and more ...

このあたりの本を再読して何かしらの気づきを得られるといいなと思う。

Docker

最近少しずつ使うようになってきたので、無理矢理にでも使っていくのを続ける。

Machine Learning

Pythonのコミュニティを始めたのでPtyhonを学ぼうと思っているけど、今更Webで使う理由はないので機械学習系をやろうと思う。 とはいえ現実的なことを考えると機械学習/データサイエンスをメインにするのではなく、それをある程度知った上で周辺のシステムをどう作っていくか、 みたいなところを考えるほうが自分の力を発揮できそうなので、そういう目線で学んでいこうと思う。

ネットワーク

基礎体力を鍛えるためにネットワークスペシャリストになろう。

仕事しすぎない

コミュニティ活動とかOSS開発をやろうと思うと時間の確保が必要なので主夫の良識の範囲で仕事をしようと思う。 とはいえ信頼残高を増やしつつ、つきあいは大事にしていこう。

2017年のふりかえり

2018年も節分がすぎ、すっかり春ですね。寒すぎなので早く暖かくなってほしい。

2017年の目標はこのようになっていました。

masayuki14.hatenablog.com

1つずつ振り返っていきましょう。

2017年にたてた目標

セルフブランディング

Rubykaigi2016に参加したことで改めて個人として活躍するには必要なことだと感じた。 まずは情熱プログラマーにもあるように「Googleで検索し最初の4ページのリンクだけを見てどんな人物だと想像するだろうか」という部分に注視して見ようと思う。 情熱プログラマーは改めて読むとほんとに良い本だ。

具体的なことは書いてないですが、セルフブランディングしようってことがわかりますね。 とりあえず「主夫」なんですよ、って感じで自己紹介していた気がします。なので今後も「主夫」ってことで通していこう。

コミュニティでの登壇

勉強会やカンファレンスで登壇する。 3年後にはRubykaigiに登壇することを目指す。 オリンピックイヤーか・・・。

京都や関西のRubyコミュニティで発表したりしようかな、と思ってました。実際には発表どころかRuby関西に1回行ったくらいでした。 しかし、OSSGateというコミュニティで活動することになり、Workshopを3回開催するという思ってもいない展開になりました。

masayuki14.hatenablog.com

oss-gate.doorkeeper.jp

oss-gate.doorkeeper.jp

また、はんなりPythonという京都のPythonコミュニティの立ち上げにも携わり発表も行っています。

hannari-python.connpass.com

hannari-python.connpass.com

もうすぐ第3回も行ないます。意外と人が集まっているので驚きです。

hannari-python.connpass.com

ブログ

Qiitaも含めてアウトプットを増やす。 最低でも月1回は書く。

これもあんまり意識しませんでしたが、ブログを8記事、Qiitaを4記事書いたようなので目標達成! 年末はアドベントカレンダーに参加すると普通に書くより色んな人に見てもらえることがわかりました。

OSSにコミット

GitHubでPullRequestを送る。 今年こそ!!

この目標は2016年のRubyKaigiの時の出会いがきっかけでたてた目標でした。 2月に大阪で開催されたOSSGateWorkshop OSS Gate大阪ワークショップ2017-02-25 - OSS Gate | Doorkeeper に参加し、Issueへの起票とPullRequestを送る体験をすることで目標を達成しました。

その後もいろんなOSSにPRを送ったりIssueを立てたりしてますし、OssGateWorkshopを京都で開催することにもなったので これに関してはなんとも不思議な1年でしたね。

シェルプログラミング

シェル芸から入って bash が面白くなってきたのでシェルプログラミングでいろいろ出来るようになる。

シェルに関する記事もかいたし、仕事でもシェルスクリプトを書く機会もあったので目標達成できました。 普段でもちょっとしたことでシェル芸を使うようになったので身についたなぁという実感も有ります。

masayuki14.hatenablog.com

masayuki14.hatenablog.com

Elixir

途中で止まってしまったプログラミングElixirをちゃんと読む。 演習問題もちゃんとやって手を動かす。

結局一度も本を開くこと無く1年が過ぎました。残念でした。

運用・監視まわり

Mackerelで独自のメトリクスを取りたい、という課題があるのでちゃんと勉強して達成する。 あわせてFuluentdとか使ってログ解析も出来るような基盤を考える。

Mackerelはエージェントをシェルスクリプトで作成して独自のメトリックを収集し可視化する、ということが出来たので目標達成です。 Qiitaにもメモ程度ですが記事を書きました。

qiita.com

ログ解析はまぁダメでしたね。ぜんぜんやってません。

まとめ

ということで、達成できなかった目標もありましたが総合しては目標達成出来た1年でした。 2017年は良い年でした。めでたしめでたし。

Vuexのはじめかた - Vuex入門者向けのはじめの一歩ガイド

これはVue.jsアドベントカレンダー#2 14日の記事です。

Vuexはflaxアーキテクチャを採用した公式プラグインで、vue.jsで利用することができます。 公式の日本語ドキュメントもあるので導入しやすい状況になっています。

とはいえ、いざ使ってみようという時には気が引けてしまうもの。 自分が導入を試みた時もいろいろと悩むポイントがありました。

  • どこから手をつけていいかわからない
  • ファイル構成のお手本が知りたい
  • スタンダードな書き方を知りたい

このあたりのことを、どう解決したかについて今回は紹介します。

はじめにすること

公式ドキュメントを読みましょう。苦手な人もいると思いますが なにを意識しながら読むかが決まっていれば読みやすくなるものです。

fluxを理解する

事前にfluxアーキテクチャについて理解する必要があります。fluxを知った上でVuexのドキュメントを読むとより理解しやすくなります。 アーキテクチャの構成要素と一方向性の特徴がつかめる程度でOKです。

このあたりの記事に解説があります。

WEB+DB PRESS Vol.97があれば特集記事があります。一番わかりやすいです。

公式ドキュメントを読む

Vuex とは何か?

事前に公式ドキュメントを一通り読んでおきましょう。流し読みでよいです。 コアコンセプトに具体的な実装方法が記載されているので、これを中心に読むと良いでしょう。 初めての時は書き方を覚えることもできないし、ぼんやりとしか理解できないと思います。 でもそれでOKです。 全体として何が出来るのかをつかむことが重要です。

  • Vuex とは何か?
  • Vuex 入門
  • コアコンセプト

の3つの章を読めばとりあえずは大丈夫です。

小さく始めよう

コアコンセプトにある5つの要素をいきなり全て取り入れることは、初心者にとって困難なことです。 そうなった時は、何から手を付けていいかわからないという状況に陥ります。 なので小さく始めて少しずつVuexを取り入れていきましょう。

サンプルコードは $ vue init webpack sample で作成されたプロジェクトを基に進めていきます。

まずはステートから

まずはステートの導入から初めましょう。以下のような何でもない Sample.vue を例にします。
ステートのドキュメント

// components/Sample.vue
<template>
  <div class="sample">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: 'sample',
  data() {
    return {
      msg: 'Welcome to My Vuex Sample',
    };
  },
};
</script>

Vuex ストアを作成

msg プロパティを表示するだけのシンプルなコンポーネントです。この msg プロパティを Vuex に移していきます。 まず、Vuexストアを作成しVueに入れます。

// main.js
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    msg: 'Hello Vuex Store.',
  },
});

new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App },
  store,
});

これでVuexを使う準備が整いました。

コンポーネントから Vuex ストアを参照する

次はVuexストアから msg ステートを読み込んで Sample.vue に表示しましょう。 コンピューテッドプロパティからストアを参照するように変更します。

// components/Sample.vue
export default {
  name: 'sample',
  data() {
    return {
      // msg: 'Welcome to My Vuex Sample.',
    };
  },

  computed: {
    msg() {
      return this.$store.state.msg;
    },
  },
};

Hello Vuex Store. が表示されましたね!おめでとう!

mapState ヘルパーを使う

msgのようなステートを複数読み込む場合には mapState ヘルパーを使うことで簡潔に記述することができます。

// components/Sample.vue
import { mapState } from 'vuex';

export default {
  name: 'sample',
  data() {
    return {
    };
  },

  computed: {
    ...mapState({
      msg: state => state.msg,
    }),
  },
};

msg の長さを取得するコンピューテッドプロパティを定義したい場合にもローカルステートのようにthisでアクセスできます。

// components/Sample.vue
computed: {
  msgLength() {
    return this.msg.length;
  },
  ...mapState({
    msg: state => state.msg,
  }),
},

これでVuexのステートを利用することが出来るようになりました。

ステートの値を変更するには

ステートの msg を更新するにはどうしたら良いでしょうか。更新ボタンをクリックすると、フォームの入力値でステートを更新するようにします。

// components/Sample.vue
<input type="text" v-model="newMsg" />
<button @click="update">更新</button>

export default {
  name: 'sample',
  data() {
    return {
      newMsg: null,
    };
  },

  methods: {
    update() {
      this.$store.state.msg = this.newMsg;
    },
  },
};

update() メソッドで msgnewMsg に入力された値に更新します。 しかしこの方法だとアプリケーションが大きくなるにつれ、どこで msg が更新されるかが追いづらくなります。 そこでミューテーションの出番です。

ミューテーションを定義する

Vuex のストアの状態を変更するためにミューテーションを定義します。
ミューテーションのドキュメント

// main.js
const store = new Vuex.Store({
  state: {
    msg: 'Hello Vuex Store.',
  },
  mutations: {
    updateMsg(state, newMsg) {
      state.msg = newMsg;
    },
  },
});

この時 updateMsg をタイプ、定義された関数をハンドラと呼びます。updateMsg というイベントを登録するようなものです。 これを起動するには store.commit('updateMsg') を呼び出す必要があります。
air-bnb のESLintルールにしているとエラーがでるので .eslintrc.js"no-param-reassign": 0 を追加します。

// components/Sample.vue
methods: {
  update() {
    // this.$store.state.msg = this.newMsg;
    this.$store.commit('updateMsg', this.newMsg);
  },
},

タイプに定数を使う

updateMsg のようなタイプに定数を使うのがVuexのスタンダードなのでそれにならいましょう。

// main.js
const UPDATE_MESSAGE = 'UPDATE_MESSAGE';

const store = new Vuex.Store({
  state: {
    msg: 'Hello Vuex Store.',
  },
  mutations: {
    [UPDATE_MESSAGE](state, newMsg) {
      state.msg = newMsg;
    },
  },
});

こうなると、commit する箇所でも同じ定数を使う必要になるので外部ファイルに定義をしましょう。 store/mutation-types.js を作成し底定数を定義します。 main.js ではそのファイルを import します。

// store/mutation-types.js
export const UPDATE_MESSAGE = 'UPDATE_MESSAGE';
export const DUMMY_TYPE = 'DUMMY_TYPE';  // ESLint対策、exportが1つだけだとErrorがでます
// main.js
import * as types from './store/mutation-types';

mutations: {
  [types.UPDATE_MESSAGE](state, newMsg) {
    state.msg = newMsg;
  },
},
// components/Sample.vue
import * as types from '@/store/mutation-types';

methods: {
  update() {
    this.$store.commit(types.UPDATE_MESSAGE, this.newMsg);
  },
},

アクションを利用する

アクションはミューテーションと似ていますが、状態を変更しない点が異なります。 APIコールなどの非同期処理を含むことができ、ミューテーションをコミットすることで状態を変更します。 文字列を繰り返すアクションを登録してみましょう。

// main.js
const store = new Vuex.Store({
  actions: {
    repeat(context) {
      let msg = context.state.msg
      context.commit(types.UPDATE_MESSAGE, `${msg} ${msg}`)
    },
  }
});

context.state で状態にアクセスし、 context.commit を呼び出すことでミューテーションにコミットできます。

アクションのディスパッチ

アクションは store.dispatch により実行されます。 「繰り返す」ボタンをクリックされた時にアクションをディスパッチします。 すると repeat アクションが実行され、表示が更新されます。

// components/Sample.vue
<button @click="repeat">繰り返す</button>

methods: {
  repeat() {
    this.$store.dispatch('repeat')
  },
},

これでVuexを使った一連のコードを実装することできました。

ファイルの分割とモジュール化

main.js に実装したVuexのコードを専用のファイルに分割しましょう。 store/index.js を作成しそちらにコードを移します。 ミューテーションやアクションもそれぞれ別の変数で管理します。

// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import * as types from './mutation-types';

Vue.use(Vuex);

const state = {
  msg: 'Hello Vuex Store.',
};

const mutations = {
  [types.UPDATE_MESSAGE](state, newMsg) {
    state.msg = newMsg;
  },
};

const actions = {
  repeat(context) {
    let msg = context.state.msg;
    context.commit(types.UPDATE_MESSAGE, `${msg} ${msg}`);
  },
};

export default new Vuex.Store({
  state,
  mutations,
  actions,
});
// main.js
import store from './store';

new Vue({
  store,
  el: '#app',
  router,
  template: '<App/>',
  components: { App },
});

機能ごとにファイルが別れて管理しやすくなりました。これでVuexの基本的な機能を使って実装することができました!

アプリケーションの構成

ファイル構成についてはアプリケーションの構成で言及されこのようになっています。

├── index.html
├── main.js
├── api
│   └── ... # API 呼び出しを抽象化する
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # モジュールを集めてストアをエクスポートする
    ├── actions.js        # アクションのルートファイル
    ├── mutations.js      # ミューテーションのルートファイル
    └── modules
        ├── cart.js       # cart モジュール
        └── products.js   # products モジュール

サンプルコードを読んでスタンダードを知る

最後にVuexを使ったプログラムのスタンダードな書き方についてです。 Vuexのリポジトリではサンプルコードが公開されています。 shopping-cartのサンプルは上記のようなアプリケーション構成になっていてとても参考になります。

store の構成に注目すると、問題領域ごとにmodule化され、アクションやミューテーションが定義されています。 また、ミューテーションを区別するミューテーションタイプは一つのファイルに定数として保存され、重複しないようになっています。

最後に

はじめてアドベントカレンダーに参加しましたが、なんとか書き終えてホッとしています。 この記事で使用したサンプルコードはこちらのリポジトリです。 ESLintの設定にAir-bnbを指定しましたが、いくつかの設定でエラーとなってしまったので、webpackの設定をおすすめします。