1. 程式人生 > >vue + vuex 的狀態管理的簡單使用

vue + vuex 的狀態管理的簡單使用

每一份總結總會有一份收穫……

VUE + vuex 的狀態管理的簡單使用:

使用webpack開發VUE的元件中,每個元件的樣式,js,資料,一般情況下都是獨立的。但是有些時候,我們希望有些資料是共享的,比如元件A中點選事件操作某個標籤的v-show=’flag’進行顯示和隱藏,元件B中也需要操作該標籤的顯示個隱藏。在這種情況下,結合父元件可以實現同時操作,但是你會發現你的程式碼比較繁瑣,當應用程式變得龐大時,也就很難管理和維護這些狀態。

而VUEX則提供了統一集中的狀態管理。

vuex的核心:
這裡寫圖片描述

流程:元件事件>dispatch>Actions(資料獲取,如從後臺獲取資料)>commit>Mutations(資料操作,改變狀態)>state>render>元件檢視

在actions獲取資料,在mutations處理資料,,在getters提供資料,這樣就很方便的管理了資料狀態。

如何簡單的使用vuex?

首先使用vue-cli手腳架初始化了一個demo
安裝vue-cli:

npm install vue-cli -g

初始化demo,如果看不懂提示則一路按回車即可。

vue init webpack-simple demo    //使用的是簡化版的webpack,完整版則是去掉-simple

當有提示有 :
cd demo
npm install
npm run dev
則初始化完成。

切換資料夾:

cd
demo

安裝node_modules:

npm install

執行專案:

npm run dev

最後的目錄結構:

這裡寫圖片描述

packege.json:

"dependencies": {
    "vue": "^2.3.3",
    "vuex": "^2.3.1"//需要自己安裝:npm install vuex --save
  },
  "devDependencies": {
    "babel-core": "^6.0.0",
    "babel-loader": "^6.0.0""babel-preset-env": "^1.5.1",
    "cross-env"
: "^3.0.0", "css-loader": "^0.25.0", "file-loader": "^0.9.0", "node-sass": "^4.5.0", "sass-loader": "^5.0.1", "vue-loader": "^12.1.0", "vue-template-compiler": "^2.3.3", "webpack": "^2.6.1", "webpack-dev-server": "^2.4.5"

小例子:

在src資料夾建立vuex的store目錄結構:

└── src
    ├── assets
    └── store
        ├── index.js          # 我們組裝模組並匯出 store 的地方
        ├── actions.js        # 根級別的 action
        ├── mutations.js      # 根級別的 mutation
        ├── getters.js        //提供資料
        ├── types.js          //型別
        └── modules           //分模組
            ├── cart.js       # 購物車模組
            └── products.js   # 產品模組
    ├── App.vue
    ├── main.js

從App.vue 開始縷。

1.首先我們希望是點選增加按鈕時觸發increment事件時count變更,在不實用VUEX之前是直接寫在了methods裡,這樣其他地方也想操作count時,就需要寫很長的程式碼,同時也不好管理。使用VUEX時,則提交給mapActions進行統一管理。

<template>
  <div id="app">
      <h3>welcome vuex-demo</h3>
      <input type="button" value="增加" @click="increment">
      <input type="button" value="減少" @click="decrement">
      <div>
        現在數字為: {{count}}, 它現在是 {{even}} //渲染
      </div>
  </div>
</template>

<script>
import {mapActions,mapGetters} from 'vuex'//匯入vuex的mapActions,mapGetters方法
export default {
    computed:mapGetters([           //使用mapGetters獲取改變後的資料
            'count',
            'even'
    ]),
    methods:mapActions([         //使用mapActions提交方法到了actions
         'increment',
         'decrement'
    ]),
}
</script>

2. actions收到資料後進一步處理,如果有請求後臺資料時,在這裡請求

actions.js:

import * as types from './types'//匯入所有定義的型別, *代表匯入所有,當然也可以不實用types,type的作用是當作引數傳遞
export default{
    increment:({ //從app.vue接收到的increment方法進一步處理
        commit //接收commit引數
    })=>{
        commit(types.INCREMENT);//進一步的提交到muations ,types.INCREMENT 是引數,等於INCREMENT 如果沒有定義types,則傳入increment,引數名稱可以自定義,但建議最好使用types統一
    },
    decrement:({
        commit
    })=>{
        commit(types.DECREMENT);
    }
}

types.js:

export const INCREMENT = 'INCREMENT'//設定常量,用作引數傳遞
export const DECREMENT = 'DECREMENT'

3. actions 提交後commit後,接著是mutations進行處理

mutations.js:

import {
    INCREMENT,  //匯入定義的types
    DECREMENT
} from './types'

import getters from './getters'   // 匯入getters

const state = {//設定狀態,在這裡定義陣列,布林,物件
    count:20,
    //flag:false
}
const mutations = {//定義mutations
    [INCREMENT](state){ //[INCREMENT]是引用types變數,接收state引數,在這裡更改和操作資料狀態,
        state.count++;
        //flag:false;
    },
    [DECREMENT](state){
        state.count--;
    }
}
export default{//匯出
    state,
    mutations,
    getters

}

gtters.js檔案:

export default{
    count:(state)=>state.count,//接收state,並return state.count
    even:(state)=>state.count%2==0?'偶數':'奇數'
}

4. 在主檔案中引用actions ,mutations

index.js:

import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'//引入actions
import mutations from './mutations'//引入mutations

Vue.use(Vuex)//vue使用vuex

export default new Vuex.Store({//匯出
    modules:{
        mutations
    },
    actions
})

5. 最後在main.js中注入:

main.js:

import Vue from 'vue'
import App from './App.vue'
import store from './store'//引入store的index.js

new Vue({
    store,//注入
    render: h => h(App)
}).$mount('#app')

這樣就完成了一個簡單的vuex的小例子,使用了vuex後,我們只需要管理store 裡的actions,mutations,getters,即可。

只有使用了,才能真正體會vuex的核心思想,個人覺得管理資料非常方便。

使用物件拓展運算子分發action

app.vue中的methods和comouted是被mapActions,mapGetters佔用了,無法寫元件自己獨立的方法。有時我們還想使用元件自己的方法時,因為有些資料不共享,所以我們希望寫在元件裡就可以。那麼則可使用使用物件拓展運算子來解決。

前面是這樣寫的,想增加方法時,無法增加,解決辦法請往下看。

import {mapActions,mapGetters} from 'vuex'//匯入vuex的方法
export default {
    computed:mapGetters([//獲取資料
            'count',
            'even'
    ]),
    methods:mapActions([//提交方法到了actions
         'increment',
         'decrement'
    ]),
}

首先修改App.vue如下:

<script>
    import {mapActions,mapGetters} from 'vuex'
    export default {
        computed:{
            ...mapGetters([  //...是物件拓展元算符
                'count',
                'decre'
            ])
             b:{//這裡寫計算屬性
                  get:()=>this.a+2,
                  set(val){
                      this.a=val;
                  }
            }
        },
        methods:{
            ...mapActions([
                'increment',
                'decrement'
            ]),
            fn(){
                console.log('這是元件的方法');
            }
        },
        mounted(){
            this.fn();//呼叫元件的方法
        }

    }
</script>

但你會發現…mapActions 和…mapGetters這方法無法使用,因為瀏覽器還沒支援,所以會報錯。解決辦法請往下:

解決vuex的…mapGetters和…mapActions報錯的方法

1.安裝babel外掛:

npm install babel-plugin-transform-object-rest-spread --save-dev
  1. 安裝es2015外掛,如果安裝了babel-preset-env外掛,就不用安裝es2015了
npm install babel-preset-es2015 --save-dev

3 . 修改.babelrc檔案:

{
  "presets": [
    ["env", { "modules": false }], //如果有了這個,就不用重新配置下面的es2015了
    ["es2015", { "modules": false }]
  ],
   "plugins": ["transform-object-rest-spread"]
}

這樣就可以解決物件拓展運算子的報錯。