一、安裝
NPM
npm install vuex --save
Yarn
yarn add vuex
在main.js引入使用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
創(chuàng)建store文件夾,里面創(chuàng)建一個(gè)js文件 store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex) // 必須顯式地通過(guò) Vue.use() 來(lái)安裝 Vuex
export default new Vuex.Store({
state: {
addCount: 0, // 顯示的數(shù)值
subCount: 1
},
mutations: {
},
actions: {
},
modules: {
}
})
二、開(kāi)始使用(顯示)---state
在vue中state有三種用法(顯示)
第一種
<div>增加的數(shù)量1:{{$store.state.addCount}}</div>
第二種
<div>減少的數(shù)量:{{countTest}}</div>
<script>
export default {
data() {
return {
countTest: null
}
},
mounted() {
this.countTest = this.$store.state.subCount;
},
}
</script>
第三種
<div>增加的數(shù)量2:{{addCount}}</div>
<script>
import {mapState} from 'vuex'
export default {
computed: {
...mapState(['addCount'])
},
}
</script>
三、Mutation
Mutation用于變更Store中的數(shù)據(jù)
① 只能通過(guò)mutation變更Store數(shù)據(jù),不可以直接操作Store中的數(shù)據(jù)。
② 通過(guò)這種方式雖然操作起來(lái)稍微繁瑣一些,但是可以集中監(jiān)控所有數(shù)據(jù)的變化。
mutations: {
/*
add 函數(shù)接收兩個(gè)參數(shù)
state: store里面的state對(duì)象(和mutition平級(jí)的state)
data: 外界傳入的值,可以隨意命名,a,b,c都可以
*/
add(state,data) {
// 每點(diǎn)擊一次,在原來(lái)的基礎(chǔ)上加 data數(shù)值
state.addCount += data;
}
},
觸發(fā)mutations的第一種方式
methods: {
handleAdd() {
// commit 的作用, 就是調(diào)用某個(gè) mutation 函數(shù)
this.$store.commit('add',2)
}
},
觸發(fā)mutations的第二種方式
export default new Vuex.Store({
state: {
addCount: 0, // 顯示的數(shù)值
subCount: 1,
aTest: '我是測(cè)試1'
},
mutations: {
/*
add 函數(shù)接收兩個(gè)參數(shù)
state: store里面的state對(duì)象(和mutition平級(jí)的state)
data: 外界傳入的值,可以隨意命名,a,b,c都可以
*/
add(state,data) {
// 每點(diǎn)擊一次,在原來(lái)的基礎(chǔ)上加 data數(shù)值
state.addCount += data;
},
sub(state,step) {
state.aTest = step;
}
},
})
<script>
// 從vuex 中 按需導(dǎo)入 mapMutations 函數(shù)
import {mapState, mapMutations} from 'vuex'
export default {
computed: {
...mapState(['addCount'])
},
// 通過(guò)導(dǎo)入的mapMutations函數(shù),將需要的mutations函數(shù),映射為當(dāng)前組件的methods方法
methods: {
// 講指定的mutations 函數(shù),映射為當(dāng)前組件的methods 函數(shù)
...mapMutations(['sub']),
handleAdd() {
this.$store.commit('add',2)
},
handleTihuan() {
this.sub('嘿嘿嘿?。?!')
}
},
}
</script>
四、Actions
Actions 用于處理異步任務(wù)。
如果通過(guò)異步操作變更數(shù)據(jù),必須通過(guò)Action,而不能使用Mutation,但是在Action中還是要通過(guò)觸發(fā)Mutation的方式間接變更數(shù)據(jù)。
觸發(fā)actions的第一種方式:
export default new Vuex.Store({
state: {
addCount: 0, // 顯示的數(shù)值
},
mutations: {
add(state) {
state.addCount += 1;
},
},
actions: {
asyncAdd(context) {
setTimeout(()=>{
context.commit('add')
},1000)
}
},
})
-----------------
methods: {
handleAdd() {
this.$store.dispatch('asyncAdd') // store 里面的方法名是哪個(gè)就在dispatch里面寫(xiě)哪個(gè)方法名
},
},
觸發(fā)actions異步任務(wù)時(shí)攜帶參數(shù):
actions: {
asyncAdd(context,step) {
setTimeout(()=>{
context.commit('add',step)
},1000)
}
}
-----
this.$store.dispatch('asyncAdd',2)
觸發(fā)actions的第二種方式:
actions: {
asyncSub(context,step) {
setTimeout(()=>{
context.commit('sub',step)
},1000)
}
},
------
import {mapState, mapMutations, mapActions} from 'vuex'
methods: {
...mapMutations(['sub']),
...mapActions(['asyncSub']),
handleSub() {
this.asyncSub(1);
},
},
------
// 或者直接在DOM元素中使用
<div>減少的數(shù)量:{{$store.state.subCount}}</div>
<!-- <el-button type="warning" @click="handleSub">減少</el-button> -->
<el-button type="warning" @click="asyncSub(2)">減少</el-button>
五、Getters
Getters用于對(duì)Store中的數(shù)據(jù)進(jìn)行加工處理形成新的數(shù)據(jù)
① Getters 可以對(duì)Store 中已有的數(shù)據(jù)加工處理之后形成新的數(shù)據(jù),類(lèi)似于Vue的計(jì)算屬性。
② Store 中數(shù)據(jù)發(fā)生變化,Getters 的數(shù)據(jù)也會(huì)跟著變化。
使用getters的第一種方式:
getters: {
// 這里的state 是store 里面state
showNumber: state => {
return '當(dāng)前最新的數(shù)據(jù)是【'+ state.testCount +'】'
}
},
-----------
// this.$store.getters.名稱(chēng)
this.$store.getters.showNumber
使用getters的第二種方式:
import {mapState, mapMutations, mapActions, mapGetters} from 'vuex'
--------------
computed: {
...mapGetters(['showNumber'])
},
-----------
<div>{{showNumber}}</div>
六、modules(我這里后面更新的是vuex@4以上的)
1、先在store文件夾創(chuàng)建一個(gè)modules文件夾,里面新建你要見(jiàn)名知意的文件,我這里就使用home.js

2.store文件夾里面的index.js文件
import {createStore} from 'vuex'
import home from './modules/home'
const store = createStore({
state() {
return {
counter: 100
}
},
mutations: {
increment(state) {
state.counter++;
},
decrement(state) {
state.counter--;
}
},
actions: {},
getters: {},
modules: {
home
}
})
export default store
3.modules文件夾里面的home.js
export const homeModule = {
/* 官方定義:默認(rèn)情況下,模塊內(nèi)部的 action 和 mutation 仍然是注冊(cè)在全局命名空間的——這樣使得多個(gè)模塊能夠?qū)? 同一個(gè) action 或 mutation 作出響應(yīng)。
Getter 同樣也默認(rèn)注冊(cè)在全局命名空間,但是目前這并非出于功能上的目的(僅僅是維持現(xiàn)狀來(lái)避免非兼容性變更)。
必須注意,不要在不同的、無(wú)命名空間的模塊中定義兩個(gè)相同的 getter 從而導(dǎo)致錯(cuò)誤。
如果希望你的模塊具有更高的封裝度和復(fù)用性,你可以通過(guò)添加 namespaced: true 的方式使其成為帶命名空間的模塊。
當(dāng)模塊被注冊(cè)后,它的所有 getter、action 及 mutation 都會(huì)自動(dòng)根據(jù)模塊注冊(cè)的路徑調(diào) 整命名
namespaced: true, // 開(kāi)啟命名空間 */
state(){
return {
homeCounter: 100
}
},
mutations: {
increment(state) {
state.homeCounter++;
}
},
actions: {
incrementAction(context) {
context.commit('increment')
}
},
getters: {
doubleHomeCounter(state) {
return state.homeCounter*2;
}
}
}
export default homeModule
4、在頁(yè)面用使用
基本的寫(xiě)法:(普通寫(xiě)法)
<template>
<div class="container">
<div>這是測(cè)試modules的組件</div>
module的值:<h3>{{$store.state.home.homeCounter}}</h3>
module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
modules的按鈕:<button @click="increment">+1</button>
modules的按鈕action:<button @click="incrementAction">+1</button>
</div>
</template>
<script>
export default {
methods: {
increment() {
this.$store.commit('home/increment')
},
incrementAction() {
this.$store.dispatch('home/incrementAction')
}
},
}
</script>
輔助函數(shù)的寫(xiě)法
第一種寫(xiě)法:(輔助函數(shù)寫(xiě)法)
<template>
<div class="container">
<div>這是測(cè)試module輔助函數(shù)的組件</div>
module的值:<h3>{{homeCounter}}</h3>
module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
modules的按鈕:<button @click="increment">+1</button>
modules的按鈕action:<button @click="incrementAction">+1</button>
</div>
</template>
<script>
import {mapState, mapMutations, mapGetters,mapActions} from 'vuex'
export default {
name: '',
components: {
},
data() {
return {
}
},
computed: {
// 寫(xiě)法一
...mapState({
homeCounter: state => state.home.homeCounter
}),
...mapGetters({
doubleHomeCounter: "home/doubleHomeCounter"
})
},
mounted() {
},
methods: {
// 寫(xiě)法一
...mapMutations({
increment: "home/increment"
}),
...mapActions({
incrementAction: "home/incrementAction"
})
},
}
</script>
第二種寫(xiě)法:(輔助函數(shù)寫(xiě)法)
<template>
<div class="container">
<div>這是測(cè)試module輔助函數(shù)的組件</div>
module的值:<h3>{{homeCounter}}</h3>
module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
modules的按鈕:<button @click="increment">+1</button>
modules的按鈕action:<button @click="incrementAction">+1</button>
</div>
</template>
<script>
import {mapState, mapMutations, mapGetters,mapActions} from 'vuex'
export default {
name: '',
computed: {
// 寫(xiě)法二
...mapState('home',['homeCounter']),
...mapGetters('home', ['doubleHomeCounter'])
},
methods: {
// 寫(xiě)法二
...mapMutations('home', ['increment']),
...mapActions('home', ['incrementAction']),
},
}
</script>
第三種寫(xiě)法:(輔助函數(shù)寫(xiě)法)
<template>
<div class="container">
<div>這是測(cè)試module輔助函數(shù)的組件</div>
module的值:<h3>{{homeCounter}}</h3>
module的值:<h3>{{$store.getters["home/doubleHomeCounter"]}}</h3>
modules的按鈕:<button @click="increment">+1</button>
modules的按鈕action:<button @click="incrementAction">+1</button>
</div>
</template>
<script>
// createNamespacedHelpers 創(chuàng)建基于某個(gè)命名空間輔助函數(shù)。它返回一個(gè)對(duì)象,對(duì)象里有新的綁定在給定命名空間值上的組件綁定輔助函數(shù):
import { createNamespacedHelpers } from 'vuex'
// 解構(gòu) createNamespacedHelpers("home") 里面的home 是你文件的名字,我這里是創(chuàng)建了home.js
const {mapState, mapMutations, mapGetters,mapActions} = createNamespacedHelpers("home")
export default {
name: '',
computed: {
// 寫(xiě)法三
...mapState(['homeCounter']),
...mapGetters(['doubleHomeCounter'])
},
mounted() {
},
methods: {
// 寫(xiě)法三
...mapMutations(['increment']),
...mapActions(['incrementAction']),
},
}
</script>