2019年時点で、仕事ではサーバサイドのプログラムを書くことが多いのですが、ちょいとwebフロントエンドを管理画面風のUIで構築してみようと思い、良さげなテンプレートを探していたところ、vue-admin-templateがシンプルで良さそうと思ったので中身を少し紐解いて見ました。(紐解くという程ではありませんが...)
で、記事本文自体は無駄に長いメモ書きに近いので、今回得られた知見を先に書いてみます。
今回得られた知見
- vue cliの基本的な使い方
- vuc cliを使ったvueアプリケーションのディレクトリ構成
- vue.config.jsによる基本的な設定
- Vuexの基本的な使い方
- ゲッター
- ミューテーション
- アクション
- モジュール
- Vue Routerの基本的な使い方
- ルーティング
- グローバルbeforeガード
- ES2015に関する知見
- 引数分割束縛
- スプレッド演算子
- mockjsの基本的な使い方
- プロトタイプを作るときくらいしか用途を思いつきませんが...
感想としては、大きすぎないオープンソースを選んで、具体的な動作を確認しながらソースコードや関連ドキュメントを読むと、効率的に理解が進むなあと思った次第です。では、以下本文です。
環境
- vue 2.6.10
- vue-router 3.0.6
- vuex 3.1.0
- vue-cli-service 3.6.0
1. 開発モードで起動(npm run dev
)すると何が起きるか
-
npm run dev
すると、package.json
の scripts -> "dev": "vue-cli-service serve"が実行される - vue-cli-serviceコマンドは
@vue/cli-service
によって提供されている -
vue-cli-service serve
すると開発サーバが起動する - vue-cli-serviceを使った開発サーバの実行時オプションの指定方法は以下の2通り
- 設定ファイルに書く
- コマンドライン引数として渡す
- e.g.
port=7777 npm run dev
とすると、環境変数process.env.portに7777がセットされる -
process.env
とはnode.jsにおける環境変数のこと -
node
でnode.jsを起動して、process.env
で確認できる
- e.g.
- vue-cliの設定ファイルは
vue.config.js
- 基本的な設定、postcss、開発サーバ周り、linter、webpackなどの設定ができる
vue.config.jsから一部抜粋
const port = process.env.port || process.env.npm_config_port || 9528 // dev port
module.exports =
publicPath: '/',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
devServer: {
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
// change xxx-api/login => mock/login
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://127.0.0.1:${port}/mock`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
},
after: require('./mock/mock-server.js')
},
-
outputDir
でnpm run build
した時のファイル出力先ディレクトリを指定する -
assetsDir
でcss、font、img、jsといったアセットファイルの出力先ディレクトリを指定する- 上記例だと、/dist/staticになる
-
lintOnSave
をtrueまたは'warning'にすると、開発中に出たlintエラーをwarningとして出力する- この設定は
eslint-loader
に依存している - デフォルトだとwarningはコンソールにだけ表示される
- ブラウザにエラー表示するには
overlay
で制御できるっぽいが、今一挙動が把握できなかった
- この設定は
-
productionSourceMap
をfalseにすると、productionビルド時にsourcemapを生成しないので、ビルドが早くなる -
devServer
で開発環境の設定ができる-
open
をtrueにするとnpm run dev した時に自動的にブラウザを開く -
proxy
はフロントエンドとバックエンド(API)を異なるホストで動かしている場合、開発用のバックエンドAPIを指定できる- e.g. RailsAPIをlocalhost:3000で動かしている場合
devServer: { proxy: 'http://localhost:3000' }
- e.g. RailsAPIをlocalhost:3000で動かしている場合
-
2. どのようにログイン処理をしているか
未ログイン状態で http://localhost:9528
にアクセスした場合
2.1 どのようにログイン判定を行って、ログインフォームを表示しているか
-
permission.js
のrouter.beforeEach(グローバルbeforeガード機能)で、cookieからトークンを取得する - cookieトークン取得は
utils/auth.js
で行っている(js-cookie
ライブラリを使用) -
to
は次にナビゲートされるルートオブジェクト。ルーティング設定ファイル(src/router/index.js)で/
のredirectが/dashboardに設定されている -
to.path
はホワイトリスト(/login)に含まれないので、リダイレクトパスに/dashboardが付いた状態で、ログインフォームを表示する
2.2 ログインフォームでどのようにログイン処理しているか
-
element-ui
のcustom-validationでユーザー名とパスワードのバリデーションを行っている- バリデーションメソッドを定義して、el-formの
:rules
に渡している
- バリデーションメソッドを定義して、el-formの
- Loginボタンを押すとvue.jsの
prevent
イベント修飾子でhandleLoginメソッドが実行される - form要素にref="loginForm"と書いているので、
this.$refs.loginForm.validate
で再度バリデーションしている - バリデーションOKなら、
this.$store.dispatch
を使ってVuexのuserモジュールのloginアクションを実行している- src/main.jsでVueオブジェクトを作る時に
store
オプションを渡すことで、各コンポーネントでthis.$store
として参照することができる
- src/main.jsでVueオブジェクトを作る時に
- loginアクションはimportしたapi/user.jsのloginを実行する
- api/user.jsのloginはutils/request.jsを使って、mock/user.jsに実装されているモックのAPIを呼び出す
- モックのAPIはユーザー名からtokenを取得して、レスポンスを返却する
- 返却されたレスポンスはutils/request.js内でaxiosの
interceptors.response
で返している(エラーコード毎にエラーメッセージを表示するのもここでやっている) - Vuexのuserモジュールのloginアクションはレスポンスデータとして取得したtokenを処理する
- SET_TOKENミューテーションをcommitする
- utils/auth.jsのsetTokenでcookieにセットする
2.3 ログイン処理した後はどのようにリダイレクトしているか
- VuexのuserモジュールのloginアクションはPromiseを返す
- handleLoginは
this.$router.push
を使って次の画面に遷移する - 遷移先のURLは、$routeをwatchしている(パラメータ変更の検知)ので、あらかじめルーティング設定のredirectパスである/dashboardがセットされている
3. どのようにログアウト処理をしているか
-
this.$store.dispatch
でVuexのuserモジュールのlogoutを呼び出す - api/user.jsのlogoutを呼び出す
- モックのAPIの/user/logoutを呼び出す
- Vuexのuserモジュールのlogoutでログアウト処理をする
- SET_TOKENミューテーションでtokenを消す
- utils/auth.jsのremoveTokenでcookieのtokenを消す
-
this.$router.push
でログイン画面に遷移する- redirectクエリパラメータは、
this.$route.fullPath
によって元画面がセットされる
- redirectクエリパラメータは、
4. ExampleのTable画面
4.1 どのようにデータを取得しているか
-
created
フックでapi/table.jsのgetListを経由して、モックAPIからデータ取得する - モックAPIでは
mockjs
ライブラリでデータを作っている
4.2 開発サーバを停止した状態のエラーハンドリング(通信エラー)はどのように行っているか
- utils/request.jsでaxiosの
interceptors.response
で通信エラーを拾っている - 拾ったエラーメッセージはelement-uiのMessageコンポーネントで表示している