Edited at

Vuex:mapStateの書き方8パターン+11サンプルコード

More than 1 year has passed since last update.

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はルート直下のステートで、モジュールではない。userprofilepostはモジュールだ。userprofileはネストした構造にした。

なお、以下で示すサンプルコードの実行はCodePenのVuex: mapState patternsで行った。


mapStateを使う前のおまじない(定型文)

VueコンポーネントでmapStateを使うためには、vuexライブラリからmapStateをインポートする必要がある。コンポーネントの<script>タグのあたまに書いておこう。

<script>

import {mapState} from 'vuex'
...


mapStateの書き方パターン集


:one: 普通のバインド

通常のバインドの書き方。


構文

computed: mapState(["ステートのキー"])

// 複数のステートをバインドすることもできる
computed: mapState(["ステートのキー", "ステートのキー", ...])

:warning: 次のような配列でない使い方はできず、Uncaught TypeError: Cannot convert undefined or null to objectというエラーが発生する。

mapState("ステートのキー") // エラー


isLoggedInをバインドする例

const app = {

name: "app",
computed: mapState(["isLoggedIn"]),
template: `<p>{{isLoggedIn}}</p>`
};


バインドされた状態

isLoggedIn: true



isLoggedInuserをバインドする例

const app = {

name: "app",
computed: mapState(["isLoggedIn", "user"]),
template: `<p>{{isLoggedIn}}{{user}}</p>`
};


バインドされた状態

isLoggedIn: true

user:
name: "suin"
profile:
facebook: null
text: "よろしく〜"
twitter: "@suin"


:two: 別名のバインド

ストアのステートを別名でバインドする書き方。


構文

computed: mapState({

別名: "ステートのキー"
})
// 複数のステートをバインドすることもできる
computed: mapState({
別名: "ステートのキー",
別名: "ステートのキー",
...
})


isLoggedInisSignedInと呼称しつつバインドする例

const app = {

name: "app",
computed: mapState({
isSignedIn: "isLoggedIn"
}),
template: `<p>{{isSignedIn}}</p>`
};


バインドされた状態

isSignedIn: true



:three: モジュール内のステートのバインド


構文

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.textuser.profile.twitterをバインドする例

const app = {

name: "app",
computed: mapState("user/profile", ["text", "twitter"]),
template: `<p>{{text}}{{twitter}}</p>`
};


バインドされた状態

text: "よろしく〜"

twitter: "@suin"


:four: 算出プロパティとステートの共存

オブジェクトスプレッド演算子(...)を使う必要がある。


構文

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



:five: 複数モジュールのモジュール内ステートのバインド

オブジェクトスプレッド演算子(...)を使う必要がある。


構文

computed: {

...mapState("モジュール名", ["モジュールステートのキー"]),
...mapState("モジュール名", ["モジュールステートのキー"]),
...
}


user.namepost.titlepost.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の書き方"


:six: モジュール内ステートの別名バインド


構文

computed: mapState("モジュールのパス", {

別名: "モジュール内のステートのキー"
})


user.nameuserNameと呼称しながらバインドする例

const app = {

name: "app",
computed: mapState("user", {
userName: "name"
}),
template: `<p>{{userName}}</p>`
};


バインドされた状態

userName: "suin"



:seven: ステート加工結果のバインド

ステートをそのままバインドするのではなく、ステートを加工した結果をバインドする方法。


構文

computed: mapState({

加工後の名称: state => 加工処理(state.加工対象のステート名)
})


isLoggedInを加工した結果をisLoggedOutとしてバインドする例

const app = {

name: "app",
computed: mapState({
isLoggedOut: state => !state.isLoggedIn
}),
template: `<p>{{isLoggedOut}}</p>`
};


バインドされた状態

isLoggedOut: false



:eight: 複雑なバインド

モジュールをまたいだ複雑なバインドをする方法。


isLoggedInuser.namepost.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のプログラミング相談室(チャット)で話しかけてください。どんな些細なものでも構いません。