序文
Vuexとは
Vuexは、Vue.jsアプリケーション用に特別に開発された状態管理モードです。集中型ストレージを使用してアプリケーションのすべてのコンポーネントの状態を管理し、対応するルールを使用して状態が予測可能な方法で変化するようにします。Vuexは、Vueの公式デバッグツールdevtools拡張機能(新しいウィンドウを開きます)にも統合されており、ゼロ構成のタイムトラベルデバッグ、状態スナップショットのインポートとエクスポートなどの高度なデバッグ機能を提供します。
これは公式ウェブサイトでのVuexの定義です。
- Vuexは、Vue.js用に特別に設計された状態管理ライブラリです。
- アプリケーション内の複数のコンポーネント間で共有する必要があるデータの集中管理を使用することで、複雑なコンポーネント通信の問題を解決し、データ共有を実現します
- 一元管理されたデータは予測可能な方法で変化します
Vuexアプリケーションシナリオ
コンポーネント化はVue.jsのコアの1つです。コンポーネント化により、開発効率と保守性が向上します。Vueプロジェクトでは、各ページをコンポーネントと見なすことができます。ほとんどのシナリオでは、コンポーネントは独立して存在するのではなく、それぞれと連携します。その他は、複雑なビジネス機能を形成し、コンポーネントの状態間の複雑な関係につながります。これらの状態を管理することは特に重要です。公式ウェブサイトの定義から、Vuexデザインの本来の目的はこの問題を解決することであることがわかります。すべてのVue.jsアプリケーションでVuexを使用できますか?
Vuexは共有状態の管理に役立ちますが、より多くの概念とフレームワークが付属しています。アプリケーションが数ページしかないほど単純な場合、Vuexの使用は間違いなく面倒で冗長であり、開発ワークロードが目に見えないほど増加し、開発効率に影響します。ただし、中規模および大規模のシングルページアプリケーションを構築する場合、複数のコンポーネントが同じ状態に依存し、複数のコンポーネントが内部メソッドを介して同じ状態を変更する必要がある場合、Vuexが最良の選択です。
Vuexのコアコンセプト
公式ウェブサイトの写真からわかるように、Vuexのコアは状態、アクション、および突然変異です。
状態
状態は、アプリケーション・コンポーネントの共有状態である。単一の状態のツリーを形成するVuexコア倉庫ストアに格納されている。ストアに格納されている状態は、すべての応答である。状態ならばVueの成分は、ストアから状態を読み取るとストア内は、ステータスが変更された場合、対応するコンポーネントがそれに応じて更新されます。
new Vuex.Store({
state: {
name: 'zhangsan',
sex: '男',
age:10
}
})
コンポーネントでVuexの状態を取得する方法は3つあります
- 最も簡単な方法は、属性を計算して取得することです
// 创建一个 Counter 组件
const Counter = {
template: `<div>{
{ count }}</div>`,
computed: {
count () {
return store.state.count
}
}
}
- ルートコンポーネントから注入されたストア経由
// 根组件,把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
const app = new Vue({
el: '#app',
store,
components: {
Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})
//子组件
const Counter = {
template: `<div>{
{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
- mapStateヘルパー関数を介して、mapState関数はオブジェクトを返します
import {
mapState } from 'vuex'
//1.基本用法
const Counter = {
template: `<div>{
{ count }}</div>`,
computed: mapState({
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
})
}
//2.组件中的计算属性名和store中的state名一致时,可以给 mapState 传一个字符串数组
const Counter = {
template: `<div>{
{ count }}</div>`,
computed: mapState(['count'])
}
//3.使用对象展开运算符
const Counter = {
template: `<div>{
{ count }}</div>`,
computed: {
...mapState(['count'])
}
}
突然変異
- ミューテーションを送信することが、Vuexストアの状態を変更する唯一の方法です
- ミューテーションはイベントに似ており、各ミューテーションには文字列イベントタイプ(タイプ)とコールバック関数(ハンドラー)があります
- 各ミューテーションコールバック関数の最初のパラメーターは状態(state)であり、2番目のオプションのパラメーターペイロード(文字列またはオブジェクト)である必要があります
- 各突然変異は同期関数でなければなりません
ミューテーションメソッドを送信する
//1.提交载荷
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10) //载荷是普通值
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
store.commit('increment', {
amount: 10 })//载荷是对象
//2.对象风格提交
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
store.commit({
type: 'increment', amount: 10 })
行動
- アクションはミューテーションを送信し、ストアの状態を直接変更することはできません
- 各アクションには、文字列イベントタイプ(タイプ)とコールバック関数(ハンドラー)があります
- アクションは、同期関数または非同期関数にすることができます
store.dispatch()を介してアクションを配布します
//1.不带参数分发
actions: {
increment ({
commit }) {
commit('increment')
}
}
store.dispatch('increment')
//2.带参数方式分发
actions: {
incrementAsync ({
commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
store.dispatch('incrementAsync', {
amount: 10 }) //以载荷形式分发
store.dispatch({
type: 'incrementAsync', amount: 10 }) //以对象形式分发
アクション配布
、アセンブリ内のアクションを配布するコンポーネントで。$のstore.dispatch(「XXX」)これを使用するか、またはstore.dispatch呼び出しにコンポーネントのメソッドをマッピングするためにmapActionsヘルパー関数を使用します(あなたがで注入格納する必要があります最初にルートノード)
import {
mapActions } from 'vuex'
export default {
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
上記の3つの主要なコア概念に加えて、ゲッターとモジュールもあります。
ゲッター
- ゲッターの機能は、vue.jsで計算されたプロパティに似ています。戻り値は、依存関係に従ってキャッシュされ、依存関係の値が変更された場合にのみ再計算されます。
- ゲッターは最初のパラメーターとして状態を受け取り、2番目のパラメーターとして他のゲッターを受け取ります。
ゲッターにアクセスする方法
//1.通过属性访问(getter会暴露为 store.getters 对象)
getters: {
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
store.getters.doneTodosCount // -> 1
//2.通过方法访问(让 getter 返回一个函数,来实现给 getter 传参)
getters: {
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
store.getters.getTodoById(2)
//3.通过mapGetters辅助函数
import {
mapGetters } from 'vuex'
export default {
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
モジュール
- ストアが大きすぎて複雑な場合、Vuexを使用すると、ストアを上から下にモジュールに分割できます。各モジュールには、独自の
状態、ミューテーション、アクション、ゲッター、さらにはネストされたサブモジュールがあります。
const moduleA = {
state: () => ({
... }),
mutations: {
... },
actions: {
... },
getters: {
... }
}
const moduleB = {
state: () => ({
... }),
mutations: {
... },
actions: {
... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
- モジュールのローカル状態モジュール内
のミューテーションとゲッター。最初に受信するパラメーターは、モジュールのローカル状態オブジェクトです。
const moduleA = {
state: () => ({
count: 0
}),
mutations: {
increment (state) {
// 这里的 `state` 对象是模块的局部状态
state.count++
}
},
getters: {
doubleCount (state) {
return state.count * 2
}
}
}
モジュール内のアクションの場合、context.stateはローカル状態であり、context.rootStateはルートノード状態です。
const moduleA = {
actions: {
incrementIfOddOnRootSum ({
state, commit, rootState }) {
if ((state.count + rootState.count) % 2 === 1) {
commit('increment')
}
}
}
}
モジュール内のゲッターの場合、3番目のパラメーターはルートノードの状態です
const moduleA = {
getters: {
sumWithRootCount (state, getters, rootState) {
return state.count + rootState.count
}
}
}