1五、VUEX-Store

一、什麼是VUEX

        Vuex是管理vue的組件狀態的工具。html

        我的理解:vuex是管理組件之間通訊的一個插件。vue

二、爲何要用VUEX

咱們知道組件之間是獨立的,組件之間想要實現通訊,我目前知道的就只有props選項,但這也僅限於父組件和子組件之間的通訊。若是兄弟組件之間想要實現通訊呢?嗯..,方法應該有。拋開怎麼實現的問題,試想一下,當作中大型項目時,面對一大堆組件之間的通訊,還有一大堆的邏輯代碼,會不會很抓狂??那爲什麼不把組件之間共享的數據給出來,在必定的規則下管理這些數據呢? 這就是Vuex的基本思想了。git

三、VUEX核心

  他有4個核心選項:state mutations  getters  actionsajax

 

 

 

3.1. State

      用來存放組件之間共享的數據。他跟組件的data選項相似,只不過data選項是用來存放組件的私有數據。vuex

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>

</head>

<script src="./js/vuex.js"></script>

<script src="./js/vue2.0.js"></script>

<body>

    <div id="app">

        <hello></hello>

    </div>

</body>

<script>

    Vue.use(Vuex);

   var myStore =  new Vuex.Store({

        state:{

            //存放組件之間共享的數據

            name:"jjk"

        },

         mutations:{

             //顯式的更改state裏的數據

         },

         getters:{

             //過濾state數據

         },

         actions:{

             //

         }

    });

 

    Vue.component('hello',{

        template:"<p>{{name}}</p>",

        computed: {

            name:function(){

                return this.$store.state.name

            }

        },

         mounted:function(){

            console.log(this)

        }

    })

    new Vue({

        el:"#app",

        data:{

            name:"dk"

        },

        store:myStore,

        mounted:function(){

            console.log(this)

        }

    })

</script>

</html>

 

 

 

 

3.2. mutations

前面講到的都是如何獲取state的數據,那如何把數據存儲到state中呢?在 Vuex store 中,實際改變 狀態(state) 的惟一方式是經過 提交(commit) 一個 mutation。  mutations下的函數接收state做爲參數,接收一個叫作payload(載荷)的東東做爲第二個參數,這個東東是用來記錄開發者使用該函數的一些信息,好比說提交了什麼,提交的東西是用來幹什麼的,包含多個字段,因此載荷通常是對象(其實這個東西跟gitcommit很相似)還有一點須要注意:mutations方法必須是同步方法!chrome

具體看實例:npm

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>

</head>

<script src="./js/vuex.js"></script>

<script src="./js/vue2.0.js"></script>

<body>

    <div id="app">

        <hello></hello>

    </div>

</body>

<script>

    Vue.use(Vuex);

   var myStore =  new Vuex.Store({

        state:{

            //存放組件之間共享的數據

            name:"jjk",

            age:18,

            num:1

        },

         mutations:{

             //顯式的更改state裏的數據

             change:function(state,a){

                //  state.num++;

               console.log(state.num += a);

               

             }

         },

         getters:{

             getAge:function(state){

                 return state.age;

             }

         },

         actions:{

             //

         }

    });

 

    Vue.component('hello',{

        template:"<p @click='changeNum'>姓名:{{name}} 年齡:{{age}} 次數:{{num}}</p>",

        computed: {

            name:function(){

                return this.$store.state.name

            },

            age:function(){

                return this.$store.getters.getAge

            },

            num:function(){

                return this.$store.state.num

            }

        },

         mounted:function(){

            console.log(this)

        },

        methods: {

            changeNum: function(){

                //在組件裏提交

                // this.num++;

                this.$store.commit('change',10)

            }

        },

        data:function(){

            return {

                // num:5

            }

        }

    })

    new Vue({

        el:"#app",

        data:{

            name:"dk"

        },

        store:myStore,

        mounted:function(){

            console.log(this)

        }

    })

</script>

</html>

 

當點擊p標籤前,chrome中顯示:json

 

 

點擊p標籤後:api

 

 

能夠看出:更改state的數據並顯示在組件中,有幾個步驟:1. mutations選項裏,註冊函數 函數裏面裝邏輯代碼。2.在組件裏,this.$store.commit('change',payload)  注意:提交的函數名要一一對應  3.觸發函數,state就會相應更改 4.在組件的計算屬性裏 this.$store.state 獲取你想要獲得的數據app

3.3. getters

有時候,咱們須要對state的數據進行篩選,過濾。這些操做都是在組件的計算屬性進行的。若是多個組件須要用到篩選後的數據,那咱們就必須處處重複寫該計算屬性函數;或者將其提取到一個公共的工具函數中,並將公共函數多處導入 - 二者都不太理想。若是把數據篩選完在傳到計算屬性裏就不用那麼麻煩了,getters就是幹這個的,你能夠把getters當作是store的計算屬性。getters下的函數接收接收state做爲第一個參數。那麼,組件是如何獲取通過getters過濾的數據呢? 過濾的數據會存放到$store.getters對象中。具體看一個例子:

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>

</head>

<script src="./js/vuex.js"></script>

<script src="./js/vue2.0.js"></script>

<body>

    <div id="app">

        <hello></hello>

    </div>

</body>

<script>

    Vue.use(Vuex);

   var myStore =  new Vuex.Store({

        state:{

            //存放組件之間共享的數據

            name:"jjk",

            age:18

        },

         mutations:{

             //顯式的更改state裏的數據

         },

         getters:{

             getAge:function(state){

                 return state.age;

             }

         },

         actions:{

             //

         }

    });

 

    Vue.component('hello',{

        template:"<p>姓名:{{name}} 年齡:{{age}}</p>",

        computed: {

            name:function(){

                return this.$store.state.name

            },

            age:function(){

                return this.$store.getters.getAge

            }

        },

         mounted:function(){

            console.log(this)

        }

    })

    new Vue({

        el:"#app",

        data:{

            name:"dk"

        },

        store:myStore,

        mounted:function(){

            console.log(this)

        }

    })

</script>

</html>

 

 

 

3.4. actions

 

既然mutations只能處理同步函數,我大js全靠異步回調吃飯,怎麼能沒有異步,因而actions出現了...  

 

        actionsmutations的區別

 

          1.Actions 提交的是 mutations,而不是直接變動狀態。也就是說,actions會經過mutations,讓mutations幫他提交數據的變動。

 

          2.Action 能夠包含任意異步操做。ajaxsetTimeoutsetInterval不在話下

 

     

 

再來看一下實例:

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>

</head>

<script src="./js/vuex.js"></script>

<script src="./js/vue2.0.js"></script>

<body>

    <div id="app">

        <hello></hello>

    </div>

</body>

<script>

    Vue.use(Vuex);

   var myStore =  new Vuex.Store({

        state:{

            //存放組件之間共享的數據

            name:"jjk",

            age:18,

            num:1

        },

         mutations:{

             //顯式的更改state裏的數據

             change:function(state,a){

                //  state.num++;

               console.log(state.num += a);

               

             },

             changeAsync:function(state,a){

                 console.log(state.num +=a);

             }

         },

         getters:{

             getAge:function(state){

                 return state.age;

             }

         },

         actions:{

        //設置延時

             add:function(context,value){

                 setTimeout(function(){

           //提交事件

                    context.commit('changeAsync',value);

                 },1000)

                 

             }

         }

    });

 

    Vue.component('hello',{

        template:`

                <div>

                    <p @click='changeNum'>姓名:{{name}} 年齡:{{age}} 次數:{{num}}</p>

                    <button @click='changeNumAnsyc'>change</button>

                </div>`,

        computed: {

            name:function(){

                return this.$store.state.name

            },

            age:function(){

                return this.$store.getters.getAge

            },

            num:function(){

                return this.$store.state.num

            }

        },

         mounted:function(){

            console.log(this)

        },

        methods: {

            changeNum: function(){

                //在組件裏提交

                // this.num++;

                this.$store.commit('change',10)

            },

        //在組件裏派發事件 當點擊按鈕時,changeNumAnsyc觸發-->actions裏的add函數被觸發-->mutations裏的changeAsync函數觸發

 

 

            changeNumAnsyc:function(){

                this.$store.dispatch('add', 5);

            }

        },

        data:function(){

            return {

                // num:5

            }

        }

    })

    new Vue({

        el:"#app",

        data:{

            name:"dk"

        },

        store:myStore,

        mounted:function(){

            console.log(this)

        }

    })

</script>

</html>

 

 

 點擊按鈕一秒後,chrome中顯示:

  

 

 先整明白 context dispatch是什麼東西:

 

        contextcontext是與 store 實例具備相同方法和屬性的對象。能夠經過context.statecontext.getters來獲取 state getters

 

        dispatch:翻譯爲派發、派遣的意思,觸發事件時,dispatch就會通知actions(跟commit同樣同樣的)參數跟commit也是同樣的。

 

    action的大致流程:

 

  1. actions選項裏添加函數(異步)並提交到對應的函數(在mutation選項裏)中  context.commit('changeAsync',value);

 

 

actions:{

             add:function(context,value){

                 setTimeout(function(){

                    context.commit('changeAsync',value);

                 },1000)

                 

             }

         }

2. 在組件裏: changeNumAnsyc:function(){this.$store.dispatch('add', 5);}  dispatch「指向」actions選項裏的函數

 

3mutations選項裏,要有對應的函數 changeAsync:function(state,a){console.log(state.num +=a);}

 

3.5. 總結

各個類型的 API各司其職,mutation 只管存,你給我(dispatch)我就存;action只管中間處理,處理完我就給你,你怎麼存我無論;Getter 我只管取,我不改的。 action放在了 methods 裏面,說明咱們應該把它當成函數來用(講道理,鉤子函數也應該能夠的) mutation是寫在store裏面的,這說明,它就是個半成品,中間量,咱們不該該在外面去操做它。getter寫在了 computed 裏面,這說明雖然 getter咱們寫的是函數,可是咱們應該把它當成計算屬性來用。

四、如何使用VUEX

3.1. 安裝vuex

  Npm install  vuex  -- save

3.2. 建立store

一、建立文件夾store,用來管理文件,具體路徑無所謂,建議放到src目錄下

二、文件夾store文件夾內建立index.js文件,這個文件咱們用來組裝模塊並導出 store 的文件

 

import Vue from 'vue'

import Vuex from 'vuex'

 

// 告訴 vue 「使用」 vuex

Vue.use(Vuex)

 

// 建立一個對象來保存應用啓動時的初始狀態

// 須要維護的狀態

const store = new Vuex.Store({

  state: {

    // 放置初始狀態 app啓動的時候的全局的初始值

    bankInf: {"name":"我是vuex的第一個數據","id":100,"bankName":"中國銀行"}

  }

})

// 整合初始狀態和變動函數,咱們就獲得了咱們所需的 store

// 至此,這個 store 就能夠鏈接到咱們的應用中

export default store

 

 

 

 

3.3. Main.js文件中註冊store

import Vue from 'vue'

import App from './App'

import router from './router'

import store from './../store/index'

 

/* eslint-disable no-new */

new Vue({

  el: '#app',

  router,

  store,

  template: '<App/>',

  components: { App }

})

 

 

 

3.4. 使用store之獲取

任意組件中使用store中的數據,就是使用計算屬性返回store中的數據到一個新屬性上

 

<div class="bank">

    <list-header :headerData="bankName"></list-header>

    04銀行詳情頁面

    <input  name="" v-model="textValue">

    <button type="button" name="獲取數據" @click="newBankName"></button>

</div>

 

 

3.5. 使用store之修改
使用命令:this.$store.commit

export default {

  ...

  computed: {

    bankName() {

      return this.$store.state.bankInf.bankName;

    }

  },

  methods: {

    newBankName: function() {

      this.$store.commit('newBankName', this.textValue)

    }

  }

 ...   

}

 

 

store中的index.js中添加mutations

 

const store = new Vuex.Store({

  state: {

    // 放置初始狀態 app啓動的時候的全局的初始值

    bankInf: {"name":"我是vuex的第一個數據","id":100,"bankName":"中國銀行"},

    count:0

  },

  mutations: {

    newBankName(state,msg) {

      state.bankInf.bankName = msg;

    }

  }

})

 

 

 

五、常見錯誤

     若是在使用中發現報錯this.$store.commit is not a function ,請打開你項目的配置文件package.json,查看你正在使用的vuex的版本,我正在使用的是vuex2.0,

 

若是想刪除舊版本的vuex並安裝新版本的vuex請使用

 

npm rm vuex --save

 

而後安裝最新的vuex

 

npm install vuex --save

 

便可解決這個錯誤,或者是查看vuex官網api修改提交mutation的語句

相關文章
相關標籤/搜索