vuex狀態(tài)管理:vuex

什么是vuex?

vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。
這是vuex官網(wǎng)的解釋。我們把它理解為在data中的屬性需要共享給其他vue組件使用的部分,即data中需要共用的屬性。

vuex的核心概念

1. this.$store:我們可以通過this.$store在vue的組件中獲取vuex的實例。

2. State:vuex中的數(shù)據(jù)源,我們可以通過this.$store.state獲取我們在vuex中聲明的全局變量的值。

3. Getter:相當(dāng)于vue中的computed,及計算屬性,可以用于監(jiān)聽、計算 state中的值的變化。

4. Mutation:vuex中去操作數(shù)據(jù)的方法(只能同步執(zhí)行)。

5. Action:用來操作Mutation 的動作,他不能直接去操作數(shù)據(jù)源,但可以把mutation變?yōu)楫惒降摹?
6. Module:模塊化,當(dāng)應(yīng)用足夠大的時候,可以把vuex分成多個子模塊。

上手vuex

  1. vue-cli構(gòu)建一個項目,用命令npm install vuex --save來安裝vuex

  2. 在src文件夾下新建一個vuex文件夾,并在文件夾下新建store.js文件

  3. 配置main.js

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,
  render: h => h(App)
})
  1. 配置store.js
import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex)

const state={
    count:1
}

export default new vuex.Store({
    state
})
  1. 在components新建一個count.vue組件,先引入,再注冊,最后調(diào)用
<template>
  <div>
    {{$store.state.count}}  <!-- 調(diào)用 -->
  </div>
</template>

<script>
import store from '@/vuex/store'  //引入
export default {
  store  //注冊
}
</script>

<style>
</style>

  1. 在定義兩個方法來改變state中的值
import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex)

const state={
    count:1
}

const mutations={
    add(state){  //此處的state是上面的state對象
        state.count++
    },
    reduce(state) {
        state.count--
    }
}

//用export default 暴露,讓外部可以使用
export default new vuex.Store({ 
    state,
    mutations
})
  1. 在組件中調(diào)用mutations的方法,要以commit的方式調(diào)用
<template>
  <div>
    {{$store.state.count}}
    <div>
      <button @click="$store.commit('add')">+</button>  
      <button @click="$store.commit('reduce')">-</button>  
    </div>
  </div>
</template>

<script>
import store from '@/vuex/store'
export default {
  store
}
</script>

<style>
</style>

從圖中可以看到,已經(jīng)實現(xiàn)了對vuex中的count加減操作

訪問state的三種方式

把stroe.js中的值,賦值給我們模板里data中的值,有三種賦值方式:

1. 通過computed的計算屬性直接賦值

computed屬性可以在輸出前,對data中的值進行改變,我們就利用這種特性把store.js中的state值賦值給我們模板中的data值。

export default {
    store,
    computed:{
        count(state){
            return this.$store.state.count
        }
    }
}

同時將模板中的$store.state.count改為count,效果不變

2. 通過mapState的對象來賦值

先引入mapState

import {mapState} from 'vuex'

再修改成如下代碼:

computed:mapState({
  count(state){
    return state.count
  }
})

3. 通過mapState的數(shù)組來賦值

computed:mapState(['count'])

這是最簡單的寫法,也是開發(fā)中最常用的方法

Mutations

接下來修改一下mutations中的add方法,給它加個參數(shù)

const mutations={
    add(state,x){
        state.count+=x
    },
    reduce(state) {
        state.count--
    }
}

在模板中相應(yīng)修改:

<div>
  <button @click="$store.commit('add',10)">+</button>  
  <button @click="$store.commit('reduce')">-</button>  
</div>


類似之前的state的屬性的調(diào)用,mutations的方法調(diào)用也很麻煩,沒有人會喜歡用$store.commit()去調(diào)用方法

模板獲取Mutations方法

先引入mapMutations

import {mapState,mapMutations} from 'vuex'

methods中加入mapMutations的方法

methods:mapMutations(['add','reduce'])

最后修改模板,就跟平時的調(diào)用方法一樣了

<div>
  <button @click="add(10)">+</button>  
  <button @click="reduce">-</button>  
</div>

getters計算過濾操作

count進行計算屬性的操作,讓它輸出前先加上100

import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex)

const state={
    count:1
}

const mutations={
    add(state,x){
        state.count+=x
    },
    reduce(state) {
        state.count--
    }
}

const getters={
    count(state){
        return state.count+=100
    }
}

//用export default 暴露,讓外部可以使用
export default new vuex.Store({ 
    state,
    mutations,
    getters
})

stategetters都是通過computed屬性輸出的,所以當(dāng)getters的介入會覆蓋掉state,所以使用es6的擴展運算符

computed:{
    ...mapState(['count']),
    count(){
        return this.$store.getters.count
    }
}


測試一下會發(fā)現(xiàn)每次都是+110,是因為點擊一下,先通過getters計算得到新的state(此時已經(jīng)+100) 然后由mutation改變+10

用mapGetters簡化模板寫法

先引入mapGetters

import {mapState,mapMutations,mapGetters} from 'vuex'

修改成如下代碼:

computed:{
    ...mapState(['count']),
    ...mapGetters(['count'])
}

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,x){
        state.count+=x
    },
    reduce(state) {
        state.count--
    }
}

const getters={
    count(state){
        return state.count+=100
    }
}

const actions={
    actions_add(context){
        context.commit('add',10)
    },
    actions_reduce({commit}){
        commit('reduce')
    }
}
//用export default 暴露,讓外部可以使用
export default new vuex.Store({ 
    state,
    mutations,
    getters,
    actions
})

兩個方法的傳參不同:

  • ontext:上下文對象,即store本身
  • {commit}:直接把commit對象傳遞過來,更加清晰

模板使用Actions方法

引入mapActions

import {mapState,mapMutations,mapGetters,mapActions} from 'vuex'

methods中寫入:

methods:{
    ...mapMutations(['add','reduce']),
    ...mapActions(['actions_add','actions_reduce'])
}

最后在模板中調(diào)用方法

<div>
  <button @click="actions_add(10)">+</button>  
  <button @click="actions_reduce">-</button>  
</div>

Module模塊組

隨著項目的復(fù)雜性增加,共享的狀態(tài)越來越多,此時就需要對狀態(tài)進行分組,分組后再進行按組編寫,實現(xiàn)狀態(tài)管理器的模塊組操作。

新增兩個文件夾,并且都新增一個store.js


test1/store.js中寫入

import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex)

const state = {
  name: 'test1'
}

export default new vuex.Store({
  state
})

復(fù)制test2/store.js中,修改name為test2

import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex)

const state = {
  name: 'test2'
}

export default new vuex.Store({
  state
})

在根目錄的store.js中引入這兩個模塊

import Vue from 'vue'
import vuex from 'vuex'
import modules1 from './test1/store'
import modules2 from './test2/store'
Vue.use(vuex)

export default new vuex.Store({
  modules: {
    modules1,
    modules2
  }
})

最后在模板中使用

<template>
  <div>
        {{name1}}
        {{name2}}
  </div>
</template>

<script>
import store from '@/vuex/store'
import {mapState} from 'vuex'
export default {
    store,
    computed:{
        ...mapState({
            name1:({modules1})=>modules1.name,
            name2:({modules2})=>modules2.name,
        }),
    }
}
</script>

<style>
</style>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 姓名:岳沁 學(xué)號:17101223458 轉(zhuǎn)載自:http://blog.csdn.net/h5_queensty...
    丘之心閱讀 2,216評論 0 1
  • vuex 入門隨記 首先肯定是要安裝vuex 這里我們使用npm包管理工具進行安裝 npm install vue...
    Yhong_閱讀 464評論 0 2
  • 安裝 npm npm install vuex --save 在一個模塊化的打包系統(tǒng)中,您必須顯式地通過Vue.u...
    蕭玄辭閱讀 3,049評論 0 7
  • 引入vuex 1.利用npm包管理工具,進行安裝 vuex。在控制命令行中輸入下邊的命令就可以了。 npm ins...
    令武閱讀 336評論 0 0
  • 利用npm包管理工具,進行安裝 vuex npm install vuex --save 建立vuex 管...
    Hassd閱讀 597評論 0 0

友情鏈接更多精彩內(nèi)容