Vuex是管理vue的組件狀態的工具。html
我的理解:vuex是管理組件之間通訊的一個插件。vue
咱們知道組件之間是獨立的,組件之間想要實現通訊,我目前知道的就只有props選項,但這也僅限於父組件和子組件之間的通訊。若是兄弟組件之間想要實現通訊呢?嗯..,方法應該有。拋開怎麼實現的問題,試想一下,當作中大型項目時,面對一大堆組件之間的通訊,還有一大堆的邏輯代碼,會不會很抓狂??那爲什麼不把組件之間共享的數據給「拎」出來,在必定的規則下管理這些數據呢? 這就是Vuex的基本思想了。git
他有4個核心選項:state mutations getters actionsajax
用來存放組件之間共享的數據。他跟組件的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>
前面講到的都是如何獲取state的數據,那如何把數據存儲到state中呢?在 Vuex store 中,實際改變 狀態(state) 的惟一方式是經過 提交(commit) 一個 mutation。 mutations下的函數接收state做爲參數,接收一個叫作payload(載荷)的東東做爲第二個參數,這個東東是用來記錄開發者使用該函數的一些信息,好比說提交了什麼,提交的東西是用來幹什麼的,包含多個字段,因此載荷通常是對象(其實這個東西跟git的commit很相似)還有一點須要注意: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
有時候,咱們須要對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>
既然mutations只能處理同步函數,我大js全靠‘異步回調’吃飯,怎麼能沒有異步,因而actions出現了...
actions和mutations的區別
1.Actions 提交的是 mutations,而不是直接變動狀態。也就是說,actions會經過mutations,讓mutations幫他提交數據的變動。
2.Action 能夠包含任意異步操做。ajax、setTimeout、setInterval不在話下
再來看一下實例:
<!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是什麼東西:
context:context是與 store 實例具備相同方法和屬性的對象。能夠經過context.state和context.getters來獲取 state 和 getters。
dispatch:翻譯爲‘派發、派遣’的意思,觸發事件時,dispatch就會通知actions(跟commit同樣同樣的)參數跟commit也是同樣的。
action的大致流程:
actions:{
add:function(context,value){
setTimeout(function(){
context.commit('changeAsync',value);
},1000)
}
}
2. 在組件裏: changeNumAnsyc:function(){this.$store.dispatch('add', 5);} 將dispatch「指向」actions選項裏的函數
3、在mutations選項裏,要有對應的函數 changeAsync:function(state,a){console.log(state.num +=a);}
各個類型的 API各司其職,mutation 只管存,你給我(dispatch)我就存;action只管中間處理,處理完我就給你,你怎麼存我無論;Getter 我只管取,我不改的。 action放在了 methods 裏面,說明咱們應該把它當成函數來用(講道理,鉤子函數也應該能夠的) mutation是寫在store裏面的,這說明,它就是個半成品,中間量,咱們不該該在外面去操做它。getter寫在了 computed 裏面,這說明雖然 getter咱們寫的是函數,可是咱們應該把它當成計算屬性來用。
Npm install vuex -- save
一、建立文件夾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
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 } })
任意組件中使用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>
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的語句