一文輕鬆搞懂Vuex
概念:
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式(官網地址:https://vuex.vuejs.org/zh/)。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。
換成我們大白話來說:Vuex就是一個狀態管理模式,可以簡單的理解為一個全域性物件,然後我們可以修改這個全域性物件裡面的屬性或者新增方法,但是我們不能像傳統JS的那種直接賦值形式來修改,我們必須得按照Vuex給我們提供的規則來修改;
Vuex的存在就是應用於解決各個元件之間傳值的問題的,說白了就是看我們傳統的vue父子元件傳值麻煩以及弊端所給我們帶來的福利;這一點官網說的很清楚:
提示:本文將以模組匯入匯出的形式來使用vuex,本文略微有點長,希望耐心的看完,當然有條件的話跟著敲一遍效果會更好!
Vuex一共給我們提供了四大物件,分別是state、mutations、getters、actions;
state:Vuex中的資料來源,我們所需要的公共資料都是儲存在這,可以簡單理解為一個透明的倉庫,可以通過this.$store.state.變數名來訪問這個倉庫裡面的資料來源;
mutations:mutations相當於是這把倉庫的鑰匙,只有通過提交mutations才能進行修改資料來源操作,也就是說你想更改這個倉庫裡面的資料就只有通過mutations來進行修改(this.$store.commit("方法名"));
getters:getters類似於vue中的computed屬性,getters的返回值會根據state中所依賴的值的狀態修改來進行改變,如果getters中依賴的state中的值沒有變化,直接讀的是快取,如果有變化這裡也會發生相應的變化,可以用於監聽state的值的變化;這裡的getters可以理解為state這個倉庫的保安,如果state的資料發生變化,這個保安就會採取相應措施進行相應變化,如果沒有發生變化,則啥事沒有則繼續混吃等死(哈哈哈,不知道比喻恰不恰當,但是是這個意思,大家理解就好,別槓精)
actions:actions和mutations很類似,只是mutations官方規定只能進行同步操作,而actions裡是可以進行非同步操作的;也就是說我們需要進行非同步操作需要在actions中來進行,然後就是actions提交的是mutations,而不是直接修改狀態的,也就是說進入這個倉庫修改資料,要先去拿到鑰匙才能修改,所以actions是提交給mutations再去執行mutations的方法的;
state的用法:
首先我們新建一個專案,搭建vue的環境我們這裡就不多贅述了,畢竟本文是講述vuex的;先在專案中安裝vuex:
安裝vuex命令:npm install vuex --save
安裝完vuex之後我們在src的目錄下新建一個vuex資料夾,同時在vuex資料夾中新建一個store.js檔案:
store.js:
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const state={ number:1 } export default new Vuex.Store({ state, })
然後我們在main.js中引用store.js,並將例項化物件的時候加入store物件
main.js
import Vue from 'vue' import App from './App' import router from './router' //引用store.js import store from './vuex/store' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, //例項化的時候加入store物件 store, components: { App }, template: '<App/>' })
然後修改一下我們的App.vue檔案
App.vue
<template> <div id="app"> <img src="./assets/logo.png"> //檢視層加資料方便觀察 <p>{{this.$store.state.number}}</p> </div> </template> <script> export default { name: 'App' } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
通過上述程式碼我們可以看到,我們在App.vue中加入了一個p標籤,vuex規定:如果我們需要讀取vuex中的資料,也就是state的資料來源倉庫,我們必須通過this.$store.state.變數名訪問
mutations的用法:
如果我們需要修改vuex中的資料來源,我們可以通過提交mutations來進行修改;
首先我們需要在我們的檢視層加個按鈕來控制:
App.js
<template> <div id="app"> <img src="./assets/logo.png"> <p>{{$store.state.number}}</p> //加個按鈕觸發事件修改資料來源 <button @click="add">按鈕</button> </div> </template> <script> export default { name: 'App', methods:{ add(){ //要修改資料來源就要根據vuex規定的方法來 this.$store.commit('addFunction'); } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
然後修改我們的store.js:
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const state={ number:1 } //新增mutations物件,state引數能獲取到上面的state const mutations={ addFunction(state){ return state.number+=1; } } //這裡一定要記得要加入到例項中,不然會報錯 export default new Vuex.Store({ state, mutations })
我們可以很直觀的看到,通過this.$store.commit('方法名')來提交mutations修改資料來源,當然我們的mutations也是可以接收引數的,第一個引數為mutations的方法名,第二個引數為mutations需要接收的引數,這樣我們的mutations就變得更加的靈活;
getters的用法:
getters類似於vue的computer用法,可以監聽state資料來源這個倉庫的資料變化,如果getters依賴state的資料發生了變化,getters中依賴的資料發生了變化state也會發生變化
首先我們可以在store.js中新增以下程式碼:
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const state={ number:1 } const getters={ //通過方法觸發 state是上面的state物件,能讀取state的值 addFunction(state){ return state.number++; } } export default new Vuex.Store({ state, //這裡一定要記得在例項化的時候加入物件 getters })
App.vue中的檢視我們可以這樣更改:
<template> <div id="app"> <img src="./assets/logo.png"> <p>頁面的值:{{$store.state.number}}</p> //加入一個標籤跟頁面的值做對比 <p>我的getters的值:{{$store.getters.addFunction}}</p> </div> </template> <script> export default { name: 'App', } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
通過上述程式碼以及檢視層我們可以清晰的看到,當我們操作了getters的時候,觸發了getters的addFunction方法,addFunction方法會改變state.number的值,這個時候number的值已經為2了,所以頁面上會顯示值為2,因為++在後,所以getters此時的值為1,也就是說當getters依賴的state.number的值在getters中發生變化的時候,state.number就會發生變化,如果state.number沒有發生變化,此時getters會優先讀快取;
actions的用法:
actions物件裡面主要是進行非同步操作,類似於mutations,不同的是actions通過提交mutations來進行更改資料,而不是直接變更資料狀態;
首先我們可以更改store.js中的程式碼:
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const state={ number:1 } const mutations={ addFunction(state){ return state.number++; } } const getters={ addFunction(state){ return state.number++; } } //context是具有store例項一樣的屬性和方法的物件 const actions={ addFunction(context){ context.commit("addFunction"); } } export default new Vuex.Store({ state, mutations, getters, //這裡記得要在例項化的時候要加上 actions })
App.vue中程式碼修改為:
<template> <div id="app"> <img src="./assets/logo.png"> <p>頁面的值:{{$store.state.number}}</p> <button @click="add">按鈕</button> </div> </template> <script> export default { name: 'App', methods:{ add(){ //actions中通過this.$store.dispatch來提交mutations進行修改 this.$store.dispatch("addFunction") } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
vuex的適用場景:
在專案開發中,可能會有很多資料或者引數我們可能需要多次讀取或者修改,像購物車等類似功能,這個時候我們的就可以用vuex來實現;vuex畢竟只是一個狀態管理模式,狀態管理模式是給我們提供方便的,但不是必需的,因為狀態管理能做的事通過其他途徑和辦法也能實現。其實個人覺得vuex跟localStorange有點相似,都是用於儲存和修改資料,為了解決跨頁面資料丟失問題;