什么是vuex
Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應用的所有組件的狀態(tài),并以相應的規(guī)則保證狀態(tài)以一種可預測的方式發(fā)生變化。Vuex 也集成到 Vue 的官方調(diào)試工具 devtools extension,提供了諸如零配置的 time-travel 調(diào)試、狀態(tài)快照導入導出等高級調(diào)試功能
好的 完全看不懂
簡單來講,我們可以把一些貨物一起放在一個倉庫之中,可以讓我們與貨物的距離只有一條通道,當我們?nèi)ゴ嫒∝浳锏臅r候,里面的東西是共有的,大家都能公用,誰都可以往里面進行存取操作
安裝、使用 vuex
npm install vuex --save
在src目錄下手動創(chuàng)建目錄文件 vuex/store.js

在main.js中配置
import Vue from 'vue'
import App from './App'
import router from './router'
import vuex from 'vuex'
Vue.use(vuex)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
在vuex/store.js中配置
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex); //必不可少
const state={
count:1
}
export default new vuex.Store({ //暴露vuex.store
state
})
在需要調(diào)用的組件中引入
import store from '@/vuex/store'
export default {
store //一定要在實例中注冊
}
獲取store中的state
<template>
<div>
{{$store.state.count}} //1
</div>
</template>
此處提前說明一下moudle 模塊組,隨著數(shù)據(jù)組件狀態(tài)越來越多,同寫一個文件不好維護

新建一個js 暴露出來
export default {
state:{
count:1
}
}
在store.js中導入
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
import states from './state'
export default new vuex.Store({
modules:{ //此參數(shù)固定
state:states
}
})
{{$store.state.state.count}} //1
其實只是相當于多了一層導入,方便我們調(diào)用維護狀態(tài)
回到開始
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
export default new vuex.Store({
state
})
簡單改變state
<template>
<div>
{{$store.state.count}}
<p>
<button @click="change">Change</button>
</p>
</div>
</template>
<script>
import store from '@/vuex/store'
export default {
store,
methods:{
change(){
this.$store.state.count++
}
}
}
</script>
<style>
</style>
強行改變vuex的state 是流氓行為(違法)
Vuex 使用單一狀態(tài)樹——是的,用一個對象就包含了全部的應用層級狀態(tài)。至此它便作為一個“唯一數(shù)據(jù)源 (SSOT)”而存在。這也意味著,每個應用將僅僅包含一個 store 實例。單一狀態(tài)樹讓我們能夠直接地定位任一特定的狀態(tài)片段,在調(diào)試的過程中也能輕易地取得整個當前應用狀態(tài)的快照。
簡單粗暴理解: 我們要把我們需要做狀態(tài)管理的量放到這里來,然后在后面的操作動它
我們有了state狀態(tài)樹,我們要改變它的狀態(tài)(值),就必須用vue指定唯一方法 mutation
更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調(diào)函數(shù) (handler)。
簡單粗暴理解:任何不以mutation的方式改變state的值,都是耍流氓(違法)
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={ //簡單編輯操作state的mutations (固定寫法)
add(state){ //此處的state就是上面的state對象
state.count++;
},
reduce(state){
state.count--;
}
}
export default new vuex.Store({
state,mutations
})
在組件中調(diào)用mutations
<template>
<div>
{{$store.state.count}}
<p>
<button @click="$store.commit('add')">+</button> //此處的調(diào)用方法注意一下 是commit
//可不是$store.mutations.add
<button @click="$store.commit('reduce')">-</button>
</p>
</div>
</template>
<script>
import store from '@/vuex/store'
export default {
store,
}
</script>
<style>
</style>
此時已經(jīng)可以通過按鈕通過mutations改變state了
在渲染vue的時候,根據(jù)鉤子函數(shù)生命周期渲染不同的DOM,一般情況下我們不用直接引用,而是賦值computed
computed屬性可以在輸出前,對data中的值進行改變,我們就利用這種特性把store.js中的state值賦值給我們模板中的data值。
export default {
store,
computed:{
count(){ //將狀態(tài)賦值給count
return this.$store.state.count;
}
}
}
相應的改變插值中的內(nèi)容 效果不變
<template>
<div>
{{count}}
<p>
<button @click="$store.commit('add')">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
</div>
</template>
此寫法稍微有些麻煩,數(shù)據(jù)多了更是繁瑣
vuex為我們提供了mapState操作
首先先引入mapState
import store from '@/vuex/store'
import {mapState} from 'vuex';
在computed中進行賦值 效果是一樣的 motations也可運行
computed:mapState({
count:state=>state.count
})
可能箭頭函數(shù)有點懵
computed:mapState({
count:function(state){
return state.count
}
})
接下來設置一下參數(shù),方法肯定有時候帶參數(shù)的嘛 在store.js中
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={
add(state,n){ =>此處增加了一個參數(shù)n
state.count+=n;
},
reduce(state){
state.count--;
}
}
export default new vuex.Store({
state,mutations
})
接下來只需要在調(diào)用mutation方法處傳入實參即可
<template>
<div>
{{count}}
<p>
<button @click="$store.commit('add',10)">+</button>
<button @click="$store.commit('reduce')">-</button>
</p>
</div>
</template>
類似開始的state 調(diào)用方法有些繁瑣 不喜歡看到$store.commit( )
模板獲取Mutations方法 vuex也為我們提供了相應的方法
import store from '@/vuex/store'
import {mapState,mapMutations} from 'vuex'; =>引入模板
方法 我們寫在methods中
methods:mapMutations([
'add','reduce'
]),
然后改變html 這樣就跟vue一樣啦
<template>
<div>
{{count}}
<p>
<button @click="add(10)">+</button>
<button @click="reduce">-</button>
</p>
</div>
</template>
getters計算過濾操作
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={
add(state,n){
state.count+=n;
},
reduce(state){
state.count--;
}
}
const getters = {
count:function(state){
return state.count +=100; =>類似filters 過濾得到state
}
}
export default new vuex.Store({
state,mutations,getters
})
在組件中獲取過濾之后的state
import store from '@/vuex/store'
import {mapState,mapMutations} from 'vuex';
export default {
store,
computed:mapState({
count:function(state){
return state.count
}
}),
methods:mapMutations([
'add','reduce'
]),
}
我們先分析一下當前代碼
我們都知道代碼屬性相同會覆蓋,也就是我如果在寫一次coumped屬性那么上面的原有屬性將會覆蓋,此處運用es6的擴展運算符進行改寫
import store from '@/vuex/store'
import {mapState,mapMutations} from 'vuex';
export default {
store,
computed:{
...mapState(["count"]),
count(){
return this.$store.getters.count;=>此時count是過濾后的state
}
},
methods:mapMutations([
'add','reduce'
]),
}
mapState通過擴展運算符將$store.state.count 映射this.count 這個this 很重要,這個映射直接映射到當前Vue的this對象上。(這句話不懂也可以記一下)
此時有測試的小伙伴可能發(fā)現(xiàn) count是110 110 加的 而不是10 10 加的
因為當count發(fā)生改變的時候 先通過getters過濾得到新的state(此時已經(jīng)+100) 然后由mutation改變+10
用mapGetters簡化模板寫法
import store from '@/vuex/store'
import {mapState,mapMutations,mapGetters} from 'vuex';
export default {
store,
computed:{
...mapState(["count"]),
...mapGetters(["count"])
},
methods:mapMutations([
'add','reduce'
]),
}
其實這里mapMutation也可以簡寫,我想大家知道怎么寫了
actions異步修改狀態(tài)
actions和之前講的Mutations功能基本一樣,不同點是,actions是異步的改變state狀態(tài),而Mutations是同步改變狀態(tài)。至于什么是異步什么是同步這里我就不做太多解釋了
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={
add(state,n){
state.count+=n;
},
reduce(state){
state.count--;
}
}
const getters = {
count:function(state){
return state.count +=100;
}
}
const actions ={
addAction(context){
context.commit('add',10) =>之前說過 mutation方法通過 commit調(diào)用 忘記了可以翻翻前面哦
},
reduceAction({commit}){
commit('reduce')
}
}
export default new vuex.Store({
state,mutations,getters,actions
})
這是兩處不同的引用mutations的方法
增加actions 當然 里面的方法名是自定義的
context --- {commit}
context:上下文對象,這里你可以理解稱store本身。
{commit}:直接把commit對象傳遞過來,可以讓方法體邏輯和代碼更清晰明了。
模板中使用actions
import store from '@/vuex/store'
import {mapState,mapMutations,mapGetters,mapActions} from 'vuex';
export default {
store,
computed:{
...mapState(["count"]),
...mapGetters(["count"])
},
methods:{
...mapMutations(['add','reduce']),
...mapActions(['addAction','reduceAction'])
}
}
其實寫法太簡單了 練兩下就soeasy了
調(diào)用異步方法名
<template>
<div>
{{count}}
<p>
<button @click="addAction">+</button>
<button @click="reduceAction">-</button>
</p>
</div>
效果相同 因為只是操作mutation的方法 將其轉(zhuǎn)換為異步
dispatch
修改了一下代碼,可以直接復制,為了讓效果更明顯
store.js
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex);
const state={
count:1
}
const mutations={
add(state,n){
state.count+=n;
},
reduce(state){
state.count--;
}
}
const actions ={
addAction(context){
context.commit('add',10)
},
reduceAction({commit}){
commit('reduce')
}
}
export default new vuex.Store({
state,mutations,actions
})
vue組件
<template>
<div>
{{count}}
<p>
<button @click="addAction">+</button>
<button @click="reduceAction">-</button>
</p>
</div>
</template>
<script>
import store from '@/vuex/store'
import {mapState,mapMutations,mapActions,mapGetters} from 'vuex';
export default {
store,
computed:{
...mapState(["count"]),
},
methods:{
// ...mapActions(['addAction','reduceAction'])
addAction(){
this.$store.dispatch('addAction',10)
},
reduceAction(){
this.$store.dispatch('reduceAction')
}
}
}
</script>
<style>
</style>
可以做下比較,dispatch其實就是相當于mutation的commit調(diào)用,我們使用map映射省略dispatch,昨天有位小伙伴問我dispatch是什么突然卡了,果然太久沒敲就尷尬了
區(qū)別:
dispatch:含有異步操作,寫法: this.$store.dispatch('actions方法名',值)
commit:同步操作,寫法:this.$store.commit('mutations方法名',值)
還是建議多用map映射
vuex-persistedstate簡單使用
npm install vuex-persistedstate -D
在store.js中引入
import Vue from 'vue'
import vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(vuex);
const state={
count:1
}
const mutations={
add(state,n){
state.count+=n;
},
reduce(state){
state.count--;
}
}
const actions ={
addAction(context){
context.commit('add',10)
},
reduceAction({commit}){
commit('reduce')
}
}
export default new vuex.Store({
plugins: [createPersistedState()], //添加這句即可 默認存儲本地localSrorage 更多配置可以百度一下
state,mutations,actions
})
因為我們的操作都是操作state的 因此只存儲state的變化 小伙伴可以自己試一下