深入理解Vuex的作用
概述
想必用過 vue.js 的童鞋,一定知道在 vue 各個組件之間傳值的痛苦,基于父子、兄弟組件,我們傳值可能會很方便,但是如果是沒有關(guān)聯(lián)的組件之間要使用同一組數(shù)據(jù),就顯得很無能為力了,而 vuex 就很好的解決了我們這種問題。所以 Vuex 也是必須掌握的,出去面試也是必問的,那么接下來我們就來簡單介紹下 vuex 是如何來管理組件的狀態(tài)的。
組件之間共享數(shù)據(jù)的方式
父向子傳值:v-bind 屬性綁定, props 接收;$parent / $children;$refs;$attrs / $listeners;
子向父傳值:v-on 事件綁定,結(jié)合 $emit 觸發(fā);$parent / $children;
兄弟組件之間共享數(shù)據(jù):EventBus;Vuex
- $on 接受數(shù)據(jù)的那個組件
- $emit 發(fā)送數(shù)據(jù)的那個組件
Vuex 原理簡介
Vuex 實現(xiàn)了一個單向數(shù)據(jù)流,在全局擁有一個 state 存放數(shù)據(jù),當(dāng)組件要更改 state 中的數(shù)據(jù)時,必須通過 mutations 進行,mutations 同時提供了訂閱者模式供外部插件調(diào)用獲取 state 數(shù)據(jù)的更新。而當(dāng)所有異步操作(常用于調(diào)用后端接口異步獲取數(shù)據(jù))或批量的同步操作需要走 actions,但 actions 也是無法直接修改 state 的,還是需要通過觸發(fā) mutations 中的方法,然后 mutations 來修改 state 的數(shù)據(jù)。數(shù)據(jù)變更后相應(yīng)推送給組件,組件重新渲染到視圖上。
vuex 是 vue 的狀態(tài)管理器,存儲的數(shù)據(jù)是響應(yīng)式的。但是并不會保存起來,刷新之后就回到了初始狀態(tài),具體做法是在 vuex 里數(shù)據(jù)改變的時候把數(shù)據(jù)拷貝一份保存到 localStorage 里面,刷新之后如果 localStorage 里有保存的數(shù)據(jù),取出來再替換 store 里的 state。
Vuex是實現(xiàn)組件全局狀態(tài)(數(shù)據(jù))管理的一種機制
可以方便的實現(xiàn)組件之間數(shù)據(jù)的共享
使用 Vuex 統(tǒng)一管理狀態(tài)的好處:
- 能夠在 Vuex 中集中管理共享的數(shù)據(jù),易于開發(fā)和后期維護
- 能夠高效的實現(xiàn)組件之間的數(shù)據(jù)共享,提高開發(fā)效率
- 存儲在 Vuex 中的數(shù)據(jù)都是響應(yīng)式的,能夠?qū)崟r保持數(shù)據(jù)與頁面的同步
什么樣的數(shù)據(jù)適合存儲到 Vuex 中
一般情況下,只有組件之間共享的數(shù)據(jù),才有必要存儲到 Vuex 中;對于組件的私有數(shù)據(jù),依舊存儲在組件自身的 data 中即可。
- 多個視圖依賴于同一個狀態(tài):例如多組件之間數(shù)據(jù)共享,在不同頁面都可以拿到用戶信息
- 來自不同視圖的行為需要改變同一個狀態(tài):比如用戶會員信息,在不同頁面可以更改
Vuex的基本使用
1. 安裝 Vuex 依賴包
npm install vuex --save
一定要加 –save,因為這個包在生產(chǎn)環(huán)境中也要使用的。
2. 導(dǎo)入 Vuex 包
import Vue from 'vue' import Vuex from 'vuex' // 掛載Vuex Vue.use(Vuex)
3.創(chuàng)建 store 對象
const store = new Vuex.Store({ // state 中存放的就是全局共享的數(shù)據(jù) state: { count: 0 } }) export default store;
4. 將store 對象掛載到 vue 實例中
new Vue({ el: '#app', render: h => h(app), router, // 將創(chuàng)建的共享數(shù)據(jù)對象,掛載到 Vue 實例中 // 所有的組件,就可以從 store 中獲取全局的數(shù)據(jù)了 store })
Vuex中的主要核心概念
1.State 數(shù)據(jù)倉庫
State 提供唯一的公共數(shù)據(jù)源,所有共享的數(shù)據(jù)都有統(tǒng)一放到 Store 的 State 中進行存儲。
組件訪問 State 中數(shù)據(jù)的第一種方式:this.$store.state.全局數(shù)據(jù)名稱
組件訪問 State 中數(shù)據(jù)的第二種方式:
// 1. 從vuex中按需導(dǎo)入 mapState 函數(shù) import { mapState } from 'vuex' // 2. 通過剛才導(dǎo)入的 mapState 函數(shù),將當(dāng)前組件需要的全局數(shù)據(jù),映射為當(dāng)前組件的 computed 計算屬性 computed: { ...mapSate(['count']) }
2. Mutation
Mutation 用于變更 Store 中的數(shù)據(jù)。
只能通過 mutation 變更 Store 數(shù)據(jù),不可以直接操作 Store 中的數(shù)據(jù),通過commit一個mutation來修改,它的本質(zhì)實際是一個function
通過這種方式雖然操作起來稍微繁瑣一些,但是可以集中監(jiān)控所有數(shù)據(jù)的變化
mutation 操作一定是同步的
我們每次提交 mutation 都會有一個記錄,Vuex 這樣做是為了更方便的記下每個數(shù)據(jù)改變的歷史和軌跡,方便監(jiān)聽以及回滾之類的操作
觸發(fā) mutations 的第一種方式:
// 在store.js中定義 mutation const store = new Vuex.Store({ state: { count: 0 }, mutations: { add(state) { state.count++ //變更狀態(tài) } } })
// 在組件中觸發(fā) mutation methods: { handle() { // 觸發(fā) mutations 的第一種方法 this.$store.commit('add') } }
觸發(fā) mutations 時傳遞參數(shù):
// store.js mutations: { addN(state, step) { //第一個參數(shù)是state,后面的參數(shù)是 store.commit 傳入的額外參數(shù),即 mutation 的載荷 payload state.count += step } } // 組件中 this.$store.commit('addN', 3) // 調(diào)用commit函數(shù),觸發(fā)mutations時攜帶參數(shù)
觸發(fā) mutations 的第二種方式:
// 1. 從 vuex 中按需導(dǎo)入 mapMutations 函數(shù) import { mapMutations } from 'vuex' // 2. 通過剛導(dǎo)入的 mapMutations 函數(shù),將指定的 mutations 函數(shù),映射為當(dāng)前組件的 methods 函數(shù) methods: { ...mapMutations(['add', 'addN']) }
注:不要在 mutations 函數(shù)中,執(zhí)行異步操作,比如添加延時器
3. Action
Action 用于處理異步任務(wù)。
如果通過異步操作變更數(shù)據(jù),必須通過 Action,而不能使用 Mutation,但是在 Action 中還是要通過觸發(fā) Mutation 的方式間接變更數(shù)據(jù)。
觸發(fā) actions 的第一種方式:
// store.js 中定義 Action const store = new Vuex.store({ //...省略其他代碼 actions: { addAsync(context, payload) { setTimeout(() => { context.commit('add') }, 1000) } } })
// 在組件中觸發(fā) Action methods: { handle() { this.$store.dispatch('addAsync', 3) } }
注:不要在 mutations 函數(shù)中,執(zhí)行異步操作,比如添加延時器
只有 mutations 中定義的函數(shù),才有權(quán)利修改 state 中的數(shù)據(jù);在 actions 中不能直接修改 state 中的數(shù)據(jù),必須通過 context.commit 觸發(fā)某個 mutation。
context:上下文對象,相當(dāng)于箭頭函數(shù)中的this,和 store 實例具有相同的屬性和方法
payload:掛載的形參
觸發(fā) actions 的第二種方式:
// 1. 從 vuex 中按需導(dǎo)入 mapActions 函數(shù) import { mapActions } from 'vuex' // 2. 通過剛導(dǎo)入的 mapActions 函數(shù),將指定的 actions 函數(shù),映射為當(dāng)前組件的 methods 函數(shù) methods: { ...mapActions(['addAsync', 'addN']) }
4. Getter
Getter用于對Store中的數(shù)據(jù)進行加工處理形成新的數(shù)據(jù)。Getter不會修改Store中的原數(shù)據(jù),只起到一個包裝器的作用。
Getter 可以對 Store 中已有的數(shù)據(jù)加工處理之后形成新的數(shù)據(jù),類似 Vue 的計算屬性 computed
和計算屬性一樣,getter 的返回值會根據(jù)它的依賴被緩存起來,且只有當(dāng)它的依賴值發(fā)生了改變才會被重新計算。即 Store 中數(shù)據(jù)發(fā)生變化,Getter 的數(shù)據(jù)也會跟著變化
// 定義 Getter const store = new Vuex.store({ state: { count: 0 }, getters: { // 實時監(jiān)聽state值的變化 showNum: state => { return '當(dāng)前最新的數(shù)量是【' + state.count + '】' } } })
使用 getters 的第一種方式:this.$store.getters.名稱
使用 getters 的第二種方式:
import { mapGetters } from 'vuex' computed: { ...mapGetters(['showNum']) }
以上就是深入理解Vuex的作用的詳細內(nèi)容,更多關(guān)于Vuex的的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
在vue中獲取微信支付code及code被占用問題的解決方法
這篇文章主要介紹了在vue中獲取微信支付code及code被占用問題的解決方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04vue2.0 和 animate.css的結(jié)合使用
animate.css是一款前端動畫庫,相似的有velocity-animate。這篇文章給大家介紹vue2.0 和 animate.css的結(jié)合使用,需要的朋友參考下吧2017-12-12Vue中使用echarts實現(xiàn)繪制人體動態(tài)圖
這篇文章主要為大家詳細介紹了Vue中如何使用echarts實現(xiàn)繪制人體動態(tài)圖,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03詳解為什么Vue中不要用index作為key(diff算法)
這篇文章主要介紹了詳解為什么Vue中不要用index作為key(diff算法),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04Vue數(shù)據(jù)驅(qū)動模擬實現(xiàn)4
這篇文章主要介紹了Vue數(shù)據(jù)驅(qū)動模擬實現(xiàn)的相關(guān)資料,介紹了Array的變異方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01Vue使用富文本編輯器Vue-Quill-Editor(含圖片自定義上傳服務(wù)、清除復(fù)制粘貼樣式等)
這篇文章主要介紹了Vue項目中使用富文本編輯器Vue-Quill-Editor(含圖片自定義上傳服務(wù)、清除復(fù)制粘貼樣式等)的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05