目錄:
- 簡介
- Vuex原理圖
- 基本用法
一、簡介
1.1、Vuex的概念和作用
Vuex 是一個專為 Vue.js 引用程序並發的狀態管理模式,它采用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式放生變化。簡單來說:Vuex是用來集中管理數據,類似於React中的Redux(回來,回家),都是基於Flux(融化了)的前端狀態管理框架。Vuex 一般小項目,寫兩個頁面是用不到的,但是中大型項目是需要用到的。
1.2、訪問Vuex官網方式
1.Vuex的官網:https://vuex.vuejs.org/zh/
2.也可以通過 Vue.js 官網進入 Vuex的官網:生態系統 -> 核心插件 -> Vuex
1.3、什么是組件狀態?
比如說你的組件會有不同的狀態,這個狀態比如說顯示或者隱藏,或者你的數據的需要展示,你的數據管理等等,都可以使用Vuex來操作。
1.4、Vuex在集中管理數據起到什么作用?
集中管理數據的,你的項目當中很多數據需要管理,包括你的組件間需要數據的傳遞,傳遞的方式我們也可以用不同的方式,如:父子組件的數據傳遞(props和觸發事件),非父子組件的數據傳遞(中央總線方式)。但是如果說你的項目太復雜,以組件的方式傳遞數據,用這種方式特別費勁,而且很亂。項目真的變大了之后,這種單線傳遞太麻煩了,所以現在基本都用Vuex。但是你的項目很簡單,沒有必要使用Vuex。
二、Vuex的原理圖
這個原理圖在官網也有,只不過我說明了一下。官網管理圖

原理圖說明:
1. Vue組件上操作,會發出(dispatch)一個動作(actions) -> 2. 提交(commit) 改變(mutation)的數據 -> 3.突變或者說改變(mutate) 狀態(state)中的數據 -> 4.改變之后,重新渲染(render)組件(Vue Components) ->5.組件就會更新,展示更新過后的數據。
三、基本使用
3.1、安裝Vuex
>npm install vuex -S
3.2、目錄結構
|-vuex-demo
|-node-modules
|-src
|-assets
|-App.vue
|-main.js
|-store.js //vuex的相關配置都在store.js中
|-.babelrc
|-...
|-webpack.config.js
3.3、創建store.js文件,在main.js中導入並且配置store對象
說明:Vuex的相關配置都在這個里面配置的
import Vue from 'vue'
import App from './App.vue'
import store from './store.js' //導入store對象
new Vue({
el: '#app',
render: h => h(App),
//配置store選項,指定為store對象,會自動將store對象注入到所有子組件中(Vue實例是根組件,其他的都是子組件),在子組件中通過this.$store訪問store對象
store //(縮寫) store:store,導入Vuex后就有store這么一個選項,store值就是你導入的store
});
注意了:Vue實例是根組件,Vue實例下注冊的組件,都是vue根組件下的子組件。
3.4、編輯 store.js
Vuex的核心是store(倉庫),相當於一個容器,一個store實例中包含以下屬性方法:
state: 定義屬性(狀態、數據) getters: 用來獲取屬性 actions: 定義方法(動作) commit: 提交變化,修改數據的唯一方式就是現實的提交mutations mutations: 定義變化(或突變),來改變數據
注:不能直接修改數據,必須是顯式提交變化,目的是為了追蹤到狀態的變化
store.js的內容(方式1:通過this.$store訪問) :
/*
* Vuex 配置
* */
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
//1.定義屬性(數據)
var state={
count:6
};
//2.創建store對象
const store = new Vuex.Store({
state //(縮寫) state:state
});
//3.導出store對象
export default store;
store.js的內容(方式2:通過mapGetters、mapActions訪問) :
/*
* Vuex 配置
* */
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
//1.定義屬性(數據)
let state={
count:6
};
//2.定義getters
let getters = {
count(state){ //參數state就是上面的state
return state.count;
}
};
//3.定義actions,要執行的操作,如流程判斷,一部請求等
const actions = {
/*increment(context){ //對應的increment的就是App.vue中綁定的事件
console.log(context);
}*/
increment({commit,state}){ //es6的語法
commit('increment'); //提交(commit)一個名為increment的變化,名稱自定義,可以認為是類型名
}
};
//4.定義mutations處理狀態(數據)的改變
const mutations = {
increment(state){ //increment函數名必須跟 actions中的commit是一樣的
state.count++;
}
};
//5.創建store對象
const store = new Vuex.Store({
state, //(縮寫) state:state
getters,
actions,
mutations
});
//6.導出store對象
export default store;
我們先來看看actions是中的context有哪些東西:
▼{getters: {…}, state: {…}, rootGetters: {…}, dispatch: ƒ, commit: ƒ, …}
▶dispatch: ƒ boundDispatch(type, payload)
▶commit: ƒ boundCommit(type, payload, options)
▶getters: {}
▶state: {__ob__: Observer}
▶rootGetters: {}
▶rootState: {__ob__: Observer}
▶__proto__: Object
很明顯是一個對象,但是我們用es6的語法使用,不然用起來比較麻煩!!!
3.5、編輯App.vue
在子組件中訪問store對象的兩種方式:
方式1:通過this.$store訪問
方式2:通過MapState、mapGetters、mapActions訪問,Vuex提供了2個方法:
MapState:獲取state mapGetters: 獲取getters,獲取屬性(數據) mapActions: 獲取actions,獲取方法(動作)
App.vue編輯(方式1:通過this.$store訪問)
<template>
<div id="app">
<!--獲取計算屬性count-->
<p>當前數據為:{{count}}</p>
</div>
</template>
<script>
export default {
name: 'app',
//方式1: 通過this.$store訪問
computed:{
count(){
return this.$store.state.count;
}
}
}
</script>
App.vue編輯(通過mapGetters、mapActions訪問)
<template>
<div id="app">
<!--觸發事件-->
<button @click="increment">增加</button>
<!--獲取數據-->
<p>當前數據為:{{count}}</p>
</div>
</template>
<script>
//先導入mapState(匹配state),mapGetters(匹配屬性),mapActions(匹配方法)方法
import {mapState,mapGetters,mapActions} from 'vuex'
export default {
name: 'app',
//方式2:通過mapGetters、mapActions訪問
//computed:mapGetters([
// 'count' //對應的store.js中的getters中的count()方法
//]),
computed:mapState([
'count' //對應就是state中的count
]),
methods:mapActions([
'increment' //匹配store.js中的actions中的increment方法
])
}
</script>
通過mapState或者mapGetters都可以獲取count值,這個就要看你喜歡用什么了,只不過mapState是直接獲取 state中的值,而mapGetters是通過定義方法獲取,而且用getters,來獲取處理過的數據不一定就是直接的count,例子下面代碼練習有。
3.6、Vuex的練習所有代碼
說明:main.js就直接引用上面的,其他的完整練習代碼如下,這邊特別注意的是:我們在調代碼的時候 可以 配合 vue-devtools 配合使用,使用方法:1-1 基本用法-第一個vue程序
1、App.vue組件
<template>
<div id="app">
<button @click="increment">增加</button>
<button @click="decrement">減少</button>
<button @click="incrementAsync">增加</button>
<!--獲取數據-->
<p>當前數據為:{{count}}</p>
<p>{{isEvenOrOdd}}</p>
</div>
</template>
<script>
import {mapState,mapGetters,mapActions} from 'vuex'
export default {
name: 'app',
//方式2:通過mapGetters、mapActions訪問
computed:mapGetters([
'count', //對應的store.js中的getters中的count()方法
'isEvenOrOdd'
]),
// computed:mapState([
// 'count' //對應就是state中的count
// ]),
methods:mapActions([
'increment',
'decrement',
'incrementAsync'
])
}
</script>
<style>
</style>
2、store.js代碼:
/*
* Vuex 配置
* */
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
//1.定義屬性(數據)
let state={
count:6
};
//2.定義getters
let getters = {
count(state){ //參數state就是上面的state
return state.count;
},
isEvenOrOdd(state){ //getters,來獲取處理過的數據不一定就是直接的count
return state.count%2 == 0?'偶數':'奇數';
}
};
//3.定義actions,要執行的操作,如流程判斷,一部請求等
const actions = {
/*increment(context){ //對應的increment的就是App.vue中綁定的事件
console.log(context);
}*/
increment({commit,state}){ //es6的語法
commit('increment'); //提交(commit)一個名為increment的變化,名稱自定義,可以認為是類型名
},
decrement({commit,state}){
//在提交條件這邊做判斷
if(state.count>10){
commit("decrement");
}
},
incrementAsync({commit,state}){
//異步操作
let p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve();
},3000);
});
p.then(()=> {
commit('increment'); //狀態改變可以是同一個操作
}).catch(() => {
console.log('異步操作');
});
}
};
//4.定義mutations處理狀態(數據)的改變
const mutations = {
increment(state){ //increment函數名必須跟 actions中的commit是一樣的
state.count++;
},
decrement(state){
state.count--;
}
};
//5.創建store對象
const store = new Vuex.Store({
state, //(縮寫) state:state
getters,
actions,
mutations
});
//6.導出store對象
export default store;
實現界面如下:
當前數據為:6
偶數
