Vuex 的嚴謹模式

前言

在開發中狀態管理是不可或缺的一部分,尤其是在使用 Vue.js 框架時,Vuex 作為 Vue 的官方狀態管理庫,提供了一種可預測的方式來管理應用狀態。為了確保狀態變更遵循可預測的流程,Vuex 提供了 strict 模式。啟用此模式後,可以更有效地捕捉錯誤。本文將探討 strict 模式的運作原理、常見錯誤示例,並提供錯誤訊息的解釋。

Vuex 的 strict: true 模式

在 Vuex 中,strict 模式的主要目的是確保所有狀態變更必須透過 mutations 進行。當 strict 設置為 true 時,Vuex 不允許直接修改狀態,這樣可以有效維持應用的可預測性。

但是如果在開發過程中遇到以下錯誤訊息:

1
2
3
[Vue warn]: Error in callback for watcher "function () {
return this._data.$$state;
}": "Error: [vuex] do not mutate vuex store state outside mutation handlers."

1
Error: [vuex] do not mutate vuex store state outside mutation handlers.

Vuex error message

則可能是因為以下兩種常見的錯誤:

  1. 直接修改 Vuex 的狀態。
  2. mutations 中使用非同步行為。

接下來,將分別展示這兩種錯誤範例及其解決方案。

錯誤範例 1

當嘗試直接修改 store.state.count

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
strict: true,
state: {
count: 0,
},
mutations: {
increment(state) {
state.count++;
console.log('increment 成功');
},
},
});

export default store;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- App.vue -->
<template>
<div id="app">
<h1>Count: {{ count }}</h1>
<button type="button" @click="addCount">正確累加</button>
<button type="button" @click="addCountError">錯誤累加</button>
</div>
</template>

<script>
import { mapState } from 'vuex';

export default {
computed: {
...mapState(['count'])
},
methods: {
addCount() {
this.$store.commit('increment'); // 正確的累加方式
},
addCountError() {
this.$store.state.count++; // 錯誤的累加方式
}
}
};
</script>

Vuex error example 1

錯誤範例 2

是在 mutations 中使用非同步行為。如果需要處理 setTimeoutAJAX 請求,應該使用 actions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
strict: true,
state: {
count: 0,
},
mutations: {
increment(state) {
state.count++;
console.log('increment 執行完成');
},
incrementError(state) {
setTimeout(() => { // 這將引發錯誤
state.count++;
console.log('incrementError 執行完成');
}, 1000);
},
},
});

export default store;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
<div id="app">
<h1>Count: {{ count }}</h1>
<button type="button" @click="addCount">正確累加</button>
<button type="button" @click="addCountError">錯誤累加</button>
</div>
</template>

<script>
import { mapState } from 'vuex';

export default {
computed: {
...mapState(['count'])
},
methods: {
addCount() {
this.$store.commit('increment'); // 正確的方法
},
addCountError() {
this.$store.commit('incrementError'); // 正確的方法,但使用 setTimeout 導致錯誤
}
}
};
</script>

Vuex error example 2

結論

啟用 Vuex 的 strict 模式是一個提升應用可預測性的重要措施。強制要求所有狀態變更必須通過 mutations 來執行,讓開發者能更容易追蹤和排查錯誤。雖然在開發過程中可能會遇到一些錯誤,但這些錯誤實際上是對良好開發習慣的提醒。遵循這些規範不僅能提高代碼的可維護性,還能提升整體的應用性能。希望這篇筆記能幫助你更好地理解 Vuex 的 strict 模式及其重要性。