このファイルを読まれる方には2種類いらっしゃるかと思います.
- Vue の学習のためソースコードを読まれる方
- プロジェクトを引き継ぎ拡張される方
後者におかれましては,プロジェクトの破綻やビューの統一性の欠損を防ぐため,以下の2ファイルも必ずお読みください.
- CODING_RULES.md
- DESIGN_RULES.md
システム自体はこのサイトにて公開されています. ただそのままデプロイしても動きません. 理由はホスティングを司る部分がセキュリティの都合で空白になっているためです.
Firestore 公式へアクセスした後,アカウントとプロジェクトを制作してください.その後「アプリを追加」にて表示されるコードを@/plugins/firebase/firebase.js
内のコメントを参考にしながらコピペしてください.それによりあなたのプロジェクトとしてこのコードが登録されます.
次に以下のコマンドを打ち込んでいきます.
npm i npm | npm i | npm i -g firebase-tools
npm run build
製品用にビルドします./dist
が生成されます.npm run serve
ローカルサーバーが起動します.Vue 側をウォッチャします.
firebase deploy
デプロイして URL に反映されるようにします.本番用.firebase serve
ローカルサーバーが起動します.firebase 側をウォッチャします.
npm i
で概ね揃いますが,いくつか追加で必要なものがあります.
- VueDevtools:Google の開発者ツールを Vue 用に拡張
- VScode:Vue を唯一サポート
研究室の public にある ***NAME***_poster_jsis_final.pdf
を参考にしてください.
ユーザー個々のデータしかないため全て Vuex で管理し,Firestore は利用していません.
actions
├ id (:num)
├ function31_id (:str)
├ character_id (:ref)
├ world_id (:ref)
├ abstract (:text)
└ note (:text)
characters
├ id (:num)
├ name (:str)
├ role (:str)
├ age (:str) // not number
├ sex (:str)
└ note (:text)
worlds
├ id (:num)
├ name (:str)
├ light (:num)
├ sound (:num)
└ note (:text)
note
function31s (物語における31の機能)
├ id (:num)
├ name (:str)
└ description (:text)
QandAs
├ id (:num)
├ question (:text)
└ answer (:text)
feedbacks
├ id (:num)
└ content (:text)
character や world のデータを action が受け取ります. データの追加や削除は参照先では発生せず,常に該当データの親ページでのみ行われます. たとえば,character の変更は参照先の ACTION ページでは発生せず, 必ず CHARACTER ページでのみ行われます. ユーザーの意識スペースを ACTION, CHARACTER, WORLD で分離する意図があるため, この制約は必ず守るようにしてください.
mutations
├ ADD_XXX (パネルの追加)
├ UPDATE_XXX (パネルの編集)
├ DELETE_XXX (パネルの削除)
└ SHOW_FEEDBACK (feedbackの表示)
feedbacks はユーザーに対する賞賛や改善点の示唆などを含んだステートです. SHOW_FEEDBASK は ADD_ACTION 時に function31_id を受け取って,その内容に応じた feedback を返します. feedback.id と action.function31_id は概ね1:1対応です.
使いやすく目的がはっきりと伝わるものを良いデザインとします.
「Atomic デザイン」や「Material デザイン」に聞き覚えがないならばREADME_TECH.md
へどうぞ.
機能ごとの最小の単位で部品を切り分け,その積み重ねで構成するデザイン. 保守性と拡張性の高さ,という開発面でのメリットに加え, 統一されたデザインによって使用者の混乱を防ぎます.
Atoms -> Molecules -> Organisms -> Templates
へとコンポーネントの粒度が大きくなっていきます.
Vuetify の採用により従来の CSS フレームワークの持つ開発コストの削減というメリットだけでなく, ページを実世界の物体(紙の積み重ね)に見立てたデザインで配置を容易に伝えることができます.
「ユーザーがタップ可能なコンポーネントの最小サイズは直径 44px」などのルールです.
詳細はDESIGN_RULES.md
にまとめてあります.
ルート直下 | |||
---|---|---|---|
.firebase | ホスティング関連 | ||
dist | 公開用ディレクトリ | ||
node_modules | 依存モジュール | ||
public | ビルド時のディレクトリ | ||
favicon.ico | サイトアイコン | ||
index.html | |||
manifest.json | PWA 設定 | ||
robots.txt | SEO 対策:クローラーのアクセス制限 | ||
src | |||
assets | |||
components | |||
Atoms | 機能上最小限の部品 | ||
Moleclules | Atoms の組み合わせ | ||
Organisms | Molecules の組み合わせ | ||
Templates | ページのフレーム | ||
plugins | |||
firebase.js | firebase の設定 | ||
vuetify.js | vuetify の設定 | ||
views | /route の表示用 | ||
App.vue | SPA の土台となるページ | ||
main.js | メイン処理,他の js ファイルを統合 | ||
registerServiceWorker.js | オフライン動作 | ||
router.js | ルート制御 | ||
store.js | Vuex 制御,今回は State のみ | ||
.browserlistrc | CSS のオートプレフィックス | ||
.firebaserc | デプロイ先の設定 | ||
firebase.json | firebase 設定 | ||
firestore.indexes.json | Firestore へのデプロイ | ||
package-lock.json | |||
package.json | 依存モジュールの管理 | ||
postcss.config.js | PostCSS 設定 |
おおまかな流れは上で説明しましたので,ここでは一部のコードに関する解説を行っていきます. 対象となるコードの性質は以下の通り.いずれもコード中のコメントで述べるには長すぎると判断しました.
- 現在の仕様では最善でなく拡張を見越した実装
- 計算量が多いが現実的に破綻しないと判断した実装
- 一般的な記述ではなく,特定の目的に強く縛られた実装
引き継がれる方へ. 特殊なコードを記述をする場合,「なぜそうしたか」をここに加筆してください. ここに残しておくことで,数ヶ月後の自身が謎めいたコードの解読に時間を浪費せずに済みます.
Vuetify のデフォルトモーダルでは開閉データが親コンポーネントに存在するため,� 表示だけを担うモーダルが密結合してしまいます. 将来1つの画面で数種のモーダルが存在するときにバグの発生が想定されるので,公式から外した形で疎結合にしています. StModal のコメントに参考にした Qiita のリンクを載せています.
/action
などのルートを使わず全て/
で管理しています.
これによりStNavigation.vue
,StNoteBoard.vue
,StFeedbackBoard.vue
が固定され,
残りの部分(右側カラム)のみが変遷していることをコード上でも示しています.
実際のコード
<template lang="pug">
v-btn(flat @click="$emit('trans', 'StActionBoard')") Action
</template>
<script>
props: ["currentBoard"]
</script>
<template lang="pug">
StNavigation(:currentBoard="currentBoard" @trans="transBoard")
</template>
<script>
methods: {
transBoard: function(board) {
this.currentBoard = board
}
}
</script>
上記のようにcurrentBoard
で表示するコンポーネントを保持しています.
ここでは ACTION だけでなく,CHARACTER や WORLD に共通する処理についても述べます.
Board は機能を,Panel は表示を担います.ただし Board は Panel に関連した機能以外とは疎結合になります.具体的には以下です.
- Board は Panel の追加と削除を担います
- Panel は Board から渡されたデータを表示します
当初は Atomic デザインに従ってStDeleteButton
->StActionPanel
->StActionBoard
のようにしていました.
この状態から削除しようとすると,Board
から孫コンポーネントであるButton
にデータを流す必要がありました.
煩雑な書き方になる一方で,Vuex で管理するべきデータでもなかったので,今回はStDeleteButton
自体を削除しました.
これにより機能はBoard
に集約しましたが,コンポーネントの記述は冗長になりました.
もし拡張時にStDeleteButton
が必要になるならば実装してください.
今回 Vuex の store で名前空間を管理する際, mutation-types.js を用いて回りくどい書き方をしています. これは過去の書き方なので,Vue の学習者やシステムの拡張者はQiita の記事を参考にしてください.