深入理解Vuex的作用
概述
想必用過 vue.js 的童鞋,一定知道在 vue 各個(gè)組件之間傳值的痛苦,基于父子、兄弟組件,我們傳值可能會(huì)很方便,但是如果是沒有關(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ù)的那個(gè)組件
- $emit 發(fā)送數(shù)據(jù)的那個(gè)組件
Vuex 原理簡介

Vuex 實(shí)現(xiàn)了一個(gè)單向數(shù)據(jù)流,在全局擁有一個(gè) state 存放數(shù)據(jù),當(dāng)組件要更改 state 中的數(shù)據(jù)時(shí),必須通過 mutations 進(jìn)行,mutations 同時(shí)提供了訂閱者模式供外部插件調(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)管理器,存儲(chǔ)的數(shù)據(jù)是響應(yīng)式的。但是并不會(huì)保存起來,刷新之后就回到了初始狀態(tài),具體做法是在 vuex 里數(shù)據(jù)改變的時(shí)候把數(shù)據(jù)拷貝一份保存到 localStorage 里面,刷新之后如果 localStorage 里有保存的數(shù)據(jù),取出來再替換 store 里的 state。
Vuex是實(shí)現(xiàn)組件全局狀態(tài)(數(shù)據(jù))管理的一種機(jī)制
可以方便的實(shí)現(xiàn)組件之間數(shù)據(jù)的共享
使用 Vuex 統(tǒng)一管理狀態(tài)的好處:
- 能夠在 Vuex 中集中管理共享的數(shù)據(jù),易于開發(fā)和后期維護(hù)
- 能夠高效的實(shí)現(xiàn)組件之間的數(shù)據(jù)共享,提高開發(fā)效率
- 存儲(chǔ)在 Vuex 中的數(shù)據(jù)都是響應(yīng)式的,能夠?qū)崟r(shí)保持?jǐn)?shù)據(jù)與頁面的同步
什么樣的數(shù)據(jù)適合存儲(chǔ)到 Vuex 中
一般情況下,只有組件之間共享的數(shù)據(jù),才有必要存儲(chǔ)到 Vuex 中;對(duì)于組件的私有數(shù)據(jù),依舊存儲(chǔ)在組件自身的 data 中即可。
- 多個(gè)視圖依賴于同一個(gè)狀態(tài):例如多組件之間數(shù)據(jù)共享,在不同頁面都可以拿到用戶信息
- 來自不同視圖的行為需要改變同一個(gè)狀態(tài):比如用戶會(huì)員信息,在不同頁面可以更改
Vuex的基本使用
1. 安裝 Vuex 依賴包
npm install vuex --save
一定要加 –save,因?yàn)檫@個(gè)包在生產(chǎn)環(huán)境中也要使用的。
2. 導(dǎo)入 Vuex 包
import Vue from 'vue' import Vuex from 'vuex' // 掛載Vuex Vue.use(Vuex)
3.創(chuàng)建 store 對(duì)象
const store = new Vuex.Store({
// state 中存放的就是全局共享的數(shù)據(jù)
state: {
count: 0
}
})
export default store;
4. 將store 對(duì)象掛載到 vue 實(shí)例中
new Vue({
el: '#app',
render: h => h(app),
router,
// 將創(chuàng)建的共享數(shù)據(jù)對(duì)象,掛載到 Vue 實(shí)例中
// 所有的組件,就可以從 store 中獲取全局的數(shù)據(jù)了
store
})
Vuex中的主要核心概念
1.State 數(shù)據(jù)倉庫
State 提供唯一的公共數(shù)據(jù)源,所有共享的數(shù)據(jù)都有統(tǒng)一放到 Store 的 State 中進(jìn)行存儲(chǔ)。
組件訪問 State 中數(shù)據(jù)的第一種方式:this.$store.state.全局?jǐn)?shù)據(jù)名稱
組件訪問 State 中數(shù)據(jù)的第二種方式:
// 1. 從vuex中按需導(dǎo)入 mapState 函數(shù)
import { mapState } from 'vuex'
// 2. 通過剛才導(dǎo)入的 mapState 函數(shù),將當(dāng)前組件需要的全局?jǐn)?shù)據(jù),映射為當(dāng)前組件的 computed 計(jì)算屬性
computed: {
...mapSate(['count'])
}
2. Mutation
Mutation 用于變更 Store 中的數(shù)據(jù)。
只能通過 mutation 變更 Store 數(shù)據(jù),不可以直接操作 Store 中的數(shù)據(jù),通過commit一個(gè)mutation來修改,它的本質(zhì)實(shí)際是一個(gè)function
通過這種方式雖然操作起來稍微繁瑣一些,但是可以集中監(jiān)控所有數(shù)據(jù)的變化
mutation 操作一定是同步的
我們每次提交 mutation 都會(huì)有一個(gè)記錄,Vuex 這樣做是為了更方便的記下每個(gè)數(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í)傳遞參數(shù):
// store.js
mutations: {
addN(state, step) { //第一個(gè)參數(shù)是state,后面的參數(shù)是 store.commit 傳入的額外參數(shù),即 mutation 的載荷 payload
state.count += step
}
}
// 組件中
this.$store.commit('addN', 3) // 調(diào)用commit函數(shù),觸發(fā)mutations時(shí)攜帶參數(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í)行異步操作,比如添加延時(shí)器
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í)行異步操作,比如添加延時(shí)器
只有 mutations 中定義的函數(shù),才有權(quán)利修改 state 中的數(shù)據(jù);在 actions 中不能直接修改 state 中的數(shù)據(jù),必須通過 context.commit 觸發(fā)某個(gè) mutation。
context:上下文對(duì)象,相當(dāng)于箭頭函數(shù)中的this,和 store 實(shí)例具有相同的屬性和方法
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用于對(duì)Store中的數(shù)據(jù)進(jìn)行加工處理形成新的數(shù)據(jù)。Getter不會(huì)修改Store中的原數(shù)據(jù),只起到一個(gè)包裝器的作用。
Getter 可以對(duì) Store 中已有的數(shù)據(jù)加工處理之后形成新的數(shù)據(jù),類似 Vue 的計(jì)算屬性 computed
和計(jì)算屬性一樣,getter 的返回值會(huì)根據(jù)它的依賴被緩存起來,且只有當(dāng)它的依賴值發(fā)生了改變才會(huì)被重新計(jì)算。即 Store 中數(shù)據(jù)發(fā)生變化,Getter 的數(shù)據(jù)也會(huì)跟著變化
// 定義 Getter
const store = new Vuex.store({
state: {
count: 0
},
getters: { // 實(shí)時(shí)監(jiān)聽state值的變化
showNum: state => {
return '當(dāng)前最新的數(shù)量是【' + state.count + '】'
}
}
})
使用 getters 的第一種方式:this.$store.getters.名稱
使用 getters 的第二種方式:
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['showNum'])
}
以上就是深入理解Vuex的作用的詳細(xì)內(nèi)容,更多關(guān)于Vuex的的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vscode 配置vue+vetur+eslint+prettier自動(dòng)格式化功能
這篇文章主要介紹了vscode 配置vue+vetur+eslint+prettier自動(dòng)格式化功能,本文通過實(shí)例代碼圖文的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
基于Vue實(shí)現(xiàn)自定義組件的方式引入圖標(biāo)
在vue項(xiàng)目中我們經(jīng)常遇到圖標(biāo),下面這篇文章主要給大家介紹了關(guān)于如何基于Vue實(shí)現(xiàn)自定義組件的方式引入圖標(biāo)的相關(guān)資料,文章通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-07-07
nginx部署訪問vue-cli搭建的項(xiàng)目的方法
本篇文章主要介紹了nginx部署訪問vue-cli搭建的項(xiàng)目的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02
用vue實(shí)現(xiàn)注冊(cè)頁效果?vue實(shí)現(xiàn)短信驗(yàn)證碼登錄
這篇文章主要為大家詳細(xì)介紹了用vue實(shí)現(xiàn)注冊(cè)頁,短信驗(yàn)證碼登錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
詳解vue開發(fā)中調(diào)用微信jssdk的問題
這篇文章主要介紹了vue開發(fā)中調(diào)用微信jssdk的問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
VueJs里利用CryptoJs實(shí)現(xiàn)加密及解密的方法示例
這篇文章主要介紹了VueJs里利用CryptoJs實(shí)現(xiàn)加密及解密的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-04-04

