VuexのmapState
は書き方にバリエーションがある。ここではできるだけ多くのパターンを紹介する。
まず、話を具体的にするために次のようなストアを前提にする。
const profile = {
namespaced: true,
state: { twitter: "@suin", facebook: null, text: "よろしく〜" }
};
const user = {
namespaced: true,
state: { name: "suin" },
modules: { profile }
};
const post = {
namespaced: true,
state: {
title: "VuexのmapStateの書き方",
tags: ["JavaScript", "Vue", "Vuex"]
}
};
const store = new Store({
state: { isLoggedIn: true },
modules: { user, post }
});
従って、ストアのステートは次の図示のようになる。isLoggedIn
はルート直下のステートで、モジュールではない。user
とprofile
、post
はモジュールだ。user
とprofile
はネストした構造にした。
なお、以下で示すサンプルコードの実行はCodePenのVuex: mapState patternsで行った。
mapStateを使う前のおまじない(定型文)
VueコンポーネントでmapState
を使うためには、vuexライブラリからmapState
をインポートする必要がある。コンポーネントの<script>
タグのあたまに書いておこう。
<script>
import {mapState} from 'vuex'
...
mapStateの書き方パターン集
普通のバインド
通常のバインドの書き方。
computed: mapState(["ステートのキー"])
// 複数のステートをバインドすることもできる
computed: mapState(["ステートのキー", "ステートのキー", ...])
次のような配列でない使い方はできず、Uncaught TypeError: Cannot convert undefined or null to object
というエラーが発生する。
mapState("ステートのキー") // エラー
isLoggedIn
をバインドする例
const app = {
name: "app",
computed: mapState(["isLoggedIn"]),
template: `<p>{{isLoggedIn}}</p>`
};
isLoggedIn: true
isLoggedIn
とuser
をバインドする例
const app = {
name: "app",
computed: mapState(["isLoggedIn", "user"]),
template: `<p>{{isLoggedIn}}{{user}}</p>`
};
isLoggedIn: true
user:
name: "suin"
profile:
facebook: null
text: "よろしく〜"
twitter: "@suin"
別名のバインド
ストアのステートを別名でバインドする書き方。
computed: mapState({
別名: "ステートのキー"
})
// 複数のステートをバインドすることもできる
computed: mapState({
別名: "ステートのキー",
別名: "ステートのキー",
...
})
isLoggedIn
をisSignedIn
と呼称しつつバインドする例
const app = {
name: "app",
computed: mapState({
isSignedIn: "isLoggedIn"
}),
template: `<p>{{isSignedIn}}</p>`
};
isSignedIn: true
モジュール内のステートのバインド
computed: mapState("モジュールのパス", ["モジュール内のステートのキー"])
// モジュール内の複数のステートをバインドすることもできる
computed: mapState("モジュールのパス", ["モジュール内のステートのキー", "モジュール内のステートのキー", ...])
user.profile
をバインドする例
const app = {
name: "app",
computed: mapState("user", ["profile"]),
template: `<p>{{profile}}</p>`
};
profile:
facebook:null
text: "よろしく〜"
twitter: "@suin"
user.profile.twitter
をバインドする例
const app = {
name: "app",
computed: mapState("user/profile", ["twitter"]),
template: `<p>{{twitter}}</p>`
};
twitter: "@suin"
user.profile.text
とuser.profile.twitter
をバインドする例
const app = {
name: "app",
computed: mapState("user/profile", ["text", "twitter"]),
template: `<p>{{text}}{{twitter}}</p>`
};
text: "よろしく〜"
twitter: "@suin"
算出プロパティとステートの共存
オブジェクトスプレッド演算子(...
)を使う必要がある。
computed: {
...mapState(["ルートステートのキー"]),
算出プロパティ1() { /* ... */ },
算出プロパティ2() { /* ... */ },
...
}
算出プロパティがあるコンポーネントにisLoggedIn
をバインドする例
const app = {
name: "app",
computed: {
...mapState(["isLoggedIn"]),
date() {
return new Date()
}
},
template: `<p>{{isLoggedIn}} {{date}}</p>`
};
date: "2018-01-07T11:11:03.779Z"
isLoggedIn: true
複数モジュールのモジュール内ステートのバインド
オブジェクトスプレッド演算子(...
)を使う必要がある。
computed: {
...mapState("モジュール名", ["モジュールステートのキー"]),
...mapState("モジュール名", ["モジュールステートのキー"]),
...
}
user.name
とpost.title
、post.tags
をバインドする例
const app = {
name: "app",
computed: {
...mapState("user", ["name"]),
...mapState("post", ["title", "tags"])
},
template: `<p>{{name}} {{title}} {{tags}}</p>`
};
name: "suin"
tags:
0: "JavaScript"
1: "Vue"
2: "Vuex"
title: "VuexのmapStateの書き方"
モジュール内ステートの別名バインド
computed: mapState("モジュールのパス", {
別名: "モジュール内のステートのキー"
})
user.name
をuserName
と呼称しながらバインドする例
const app = {
name: "app",
computed: mapState("user", {
userName: "name"
}),
template: `<p>{{userName}}</p>`
};
userName: "suin"
ステート加工結果のバインド
ステートをそのままバインドするのではなく、ステートを加工した結果をバインドする方法。
computed: mapState({
加工後の名称: state => 加工処理(state.加工対象のステート名)
})
isLoggedIn
を加工した結果をisLoggedOut
としてバインドする例
const app = {
name: "app",
computed: mapState({
isLoggedOut: state => !state.isLoggedIn
}),
template: `<p>{{isLoggedOut}}</p>`
};
isLoggedOut: false
複雑なバインド
モジュールをまたいだ複雑なバインドをする方法。
isLoggedIn
、user.name
、post.title
をバインドする例
const app = {
name: "app",
computed: mapState({
isLoggedIn: "isLoggedIn",
userName: state => state.user.name,
postTitle: state => state.post.title
}),
template: `<p>{{isLoggedIn}} {{userName}} {{postTitle}}</p>`
};
isLoggedIn: true
postTitle: "VuexのmapStateの書き方"
userName: "suin"
質疑応答
質問などは、ここにコメントを残すかsuinのプログラミング相談室(チャット)で話しかけてください。どんな些細なものでも構いません。