Vuex的全面用法總結

?

1. vuex簡介

vuex是專門用來管理vue.js應用程序中狀態的一個插件。他的作用是將應用中的所有狀態都放在一起,集中式來管理。需要聲明的是,這里所說的狀態指的是vue組件中data里面的屬性。了解vue的同學應該是明白data是怎么回事的吧,如果不懂的話,建議先學完vue的基礎知識再看vuex。

?

?

2. vuex的組成結構示意圖

vuex的特點是把數據單獨隔離,形成一棵樹狀圖。單獨隔離就意味著它有自己的生態系統。輸入和輸出,其中action作為數據的輸入,state作為數據的輸出。如下圖:

vuex里有這么一個規則:

只能在mutaions里修改state,actions不能直接修改state

?

mutations即變化,修改state的數據,而且只能是同步的,不能存在異步的操作。如果需要異步怎么辦呢?把異步操作放在actions里,拿到數據再通過mutations同步處理。vuex做的其實是把職權明確了,責任細分了。所以它文檔里也說,小系統可以不用。狀態數據少,沒有細分的必要。

3. vuex 的核心概念

?

3.1 store

vuex 中最關鍵的是store對象,這是vuex的核心。可以說,vuex這個插件其實就是一個store對象,每個vue應用僅且僅有一個store對象。

3.1.1 創建store

const store = new Vuex.Store({...});

可見,store是Vuex.Store這個構造函數new出來的實例。在構造函數中可以傳一個對象參數。這個參數中可以包含5個對象:

  • 1.state – 存放狀態

  • 2.getters – state的計算屬性

  • 3.mutations – 更改狀態的邏輯,同步操作

  • 4.actions – 提交mutation,異步操作

  • 5.mudules – 將store模塊化

關于store,需要先記住兩點:

  • 1. store 中存儲的狀態是響應式的,當組件從store中讀取狀態時,如果store中的狀態發生了改變,那么相應的組件也會得到更新;

  • 2. 不能直接改變store中的狀態。改變store中的狀態的唯一途徑是提交(commit)mutations。這樣使得我們可以方便地跟蹤每一個狀態的變化。

3.1.2 一個完整的store的結構是這樣的

const store = new Vuex.Store({state: {// 存放狀態},getters: {// state的計算屬性},mutations: {// 更改state中狀態的邏輯,同步操作},actions: {// 提交mutation,異步操作},// 如果將store分成一個個的模塊的話,則需要用到modules。//然后在每一個module中寫state, getters, mutations, actions等。modules: {a: moduleA,b: moduleB,// ...}
});

3.2 state

state上存放的,說的簡單一些就是變量,也就是所謂的狀態。沒有使用 state 的時候,我們都是直接在 data 中進行初始化的,但是有了 state 之后,我們就把 data 上的數據轉移到 state 上去了。另外有些狀態是組件私有的狀態,稱為組件的局部狀態,我們不需要把這部分狀態放在store中去。

?

3.2.1 如何在組件中獲取vuex狀態

由于vuex的狀態是響應式的,所以從store中讀取狀態的的方法是在組件的計算屬性中返回某個狀態。

import store from 'store';
const Counter = {template: `<div>{{ count }}</div>`,computed: {count () {// 獲取store中的狀態return store.state.count;}}
}

這樣,組件中的狀態就與store中的狀態關聯起來了。每當store.state.count發生變化時,都會重新求取計算屬性,從而更新DOM。

然而,每個組件中都需要反復倒入store。可以將store注入到vue實例對象中去,這樣每一個子組件中都可以直接獲取store中的狀態,而不需要反復的倒入store了。
?

const app = new Vue({el: '#app',// 把 store 對象注入到了store,components: { Counter },template: `<div><counter></counter></div>`
});

這樣可以在子組件中使用this.$store.state.count訪問到state里面的count這個狀態

const Counter = {template: `<div>{{ count }}</div>`,computed: {count () {// 獲取store中的狀態return this.$store.state.count;}}
}

3.2.2 mapState

當一個組件獲取多種狀態的時候,則在計算屬性中要寫多個函數。為了方便,可以使用mapState輔助函數來幫我們生成計算屬性。

import { mapState } from ?'vuex';
export default {// ...data (){localState: 1}computed: mapState({// 此處的state即為store里面的statecount: state => state.count,// 當計算屬性的名稱與state的狀態名稱一樣時,可以省寫// 映射 this.count1 為 store.state.count1count1,//'count'等同于 ‘state => state.count’countAlias: 'count',countPlus (state){// 使用普通函數是為了保證this指向組件對象return state.count + this.localState;}})
}
//上面是通過mapState的對象來賦值的,還可以通過mapState的數組來賦值
computed: mapState(['count']);
//這種方式很簡潔,但是組件中的state的名稱就跟store中映射過來的同名

對象擴展運算符

mapState 函數返回的是一個對象,為了將它里面的計算屬性與組件本身的局部計算屬性組合起來,需要用到對象擴展運算符。

computed: {localState () { ...mapState ({})}
}

這樣,mapState中的計算屬性就與localState計算屬性混合一起了。

3.3 getters

有時候我們需要從 store 中的 state 中派生出一些狀態,例如對列表進行過濾并計數。此時可以用到getters,getters可以看作是store的計算屬性,其參數為state。

const store = new Vuex.Store({state: {todos: [{id: 1, text: 'reading', done: true},{id: 2, text: 'playBastketball', done: false}]},getters: {doneTodos: state => {return state.todos.filter(todo => todo.done);}}
});

3.3.1 獲取getters里面的狀態,方法一

store.getters.doneTodos // ?[{ id: 1, text: 'reading', done: true }]
//在組件中,則要寫在計算屬性中,
computed: {doneTodos () {return this.$store.getters.doneTodos;}
}

3.3.2 使用mapGetters獲取getters里面的狀態:方法二

import {mapState, mapGetters} from 'vuex';
computed: {
...mapState(['increment']),
...mapGetters(['doneTodos'])
}

3.4 mutations

mutations里面是如何更改state中狀態的邏輯。更改Vuex中的state的唯一方法是,提交mutation,即store.commit(‘increment’)。

3.4.1 提交載荷(payload)

可以向commit傳入額外的參數,即mutation的載荷。

mutations: {increment(state, n){state.count += n;}
}
store.commit('increment', 10);

payload還可以是一個對象。

mutations: {increment(state, payload)state.count += payload.amount;
}
}
store.commit('increment', {amount: 10});

還可以使用type屬性來提交mutation。

store.commit({type: 'increment',amount: 10
});
// mutations保持不變
mutations: {increment(state, payload){state.count += payload.amount;}
}

注意:mutation必須是同步函數,不能是異步的,這是為了調試的方便。

?

3.4.2 在組件中提交mutations

那么mutation應該在哪里提交呢? 因為js是基于事件驅動的,所以改變狀態的邏輯肯定是由事件來驅動的,所以store.commit(‘increment’)是在組件的methods中來執行的。

方法1: 在組件的methods中提交

methods: {increment(){this.$store.commit('increment');}
}

方法2: 使用mapMutaions

用 mapMutations 輔助函數將組件中的 methods 映射為 store.commit 調用。

import { mapMutaions } from 'vuex';
export default {// ...methods: {...mapMutaions(['increment' // 映射 this.increment() 為 this.$store.commit('increment')]),...mapMutaions([add: 'increment' // 映射 this.add() 為 this.$store.commit('increment')])}
}// 因為mutation相當于一個method,所以在組件中,可以這樣來使用
<button @click="increment">+</button>

3.5 actions

因為mutations中只能是同步操作,但是在實際的項目中,會有異步操作,那么actions就是為了異步操作而設置的。這樣,就變成了在action中去提交mutation,然后在組件的methods中去提交action。只是提交actions的時候使用的是dispatch函數,而mutations則是用commit函數。

3.5.1 一個簡單的action

const store = new Vuex.Store({state: {count: 0},mutations: {increment(state){state.count++;}},actions: {increment(context){context.commit('increment');}/* 可以用參數結構的方法來寫actionincrement({commit}){commit('increment');}*/}
});// action函數接受一個context參數,這個context具有與store實例相同的方法和屬性。// 分發action
store.dispatch('increment');

action同樣支持payload和對象方式來分發,格式跟commit是一樣的,不再贅述。

?

4.5.2 在組件中分發action

方法1: 在組件的methods中,使用this.$store.dispatch(‘increment’)。

方法2: 使用mapActions,跟mapMutations是類似的。

import { mapActions } from 'vuex'
export default {// ...methods: {...mapActions(['increment' // 映射 this.increment() 為 this.$store.dispatch('increment')]),...mapActions({add: 'increment' // 映射 this.add() 為 this.$store.dispatch('increment')
})
}
}// 同樣在組件中,可以這樣來使用
<button @click="increment">+</button>

?

3.5.3 組合actions

因為action是異步的,那么我們需要知道這個異步函數什么時候結束,以及等到其執行后,會利用某個action的結果。這個可以使用promise來實現。在一個action中返回一個promise,然后使用then()回調函數來處理這個action返回的結果。

actions:{actionA({commit}){return new Promise((resolve, reject) => {setTimeout(() => {commit('someMutation');resolve();},1000);})}
}// 這樣就可以操作actionA返回的結果了
store.dispatch('actionA').then(() => {// dosomething ...
});// 也可以在另一個action中使用actionA的結果
actions: {// ...actionB({ dispatch, commit }){return dispatch('actionA').then(() => {commit('someOtherMutation');})}
}

4 mudules

module是為了將store拆分后的一個個小模塊,這么做的目的是因為當store很大的時候,分成模塊的話,方便管理。

4.1 每個module擁有自己的state, getters, mutation, action

const moduleA = {state: {...},getters: {...},mutations: {....},actions: {...}
}const moduleB = {state: {...},getters: {...},mutations: {....},actions: {...}
}const store = new Vuex.Store({modules: {a: moduleA,b: moduleB}
});store.state.a // 獲取moduleA的狀態
store.state.b // 獲取moduleB的狀態

4.2 模塊內部的狀態

對于模塊內部的mutation和getter,接受的第一個參數是模塊的局部狀態state。順便說一下,根結點的狀態為rootState。

?

const moduleA = {state: { count: 0},getters: {doubleCount(state){return state.count * 2;}},mutations: {increment(state){state.count ++ ;}},actions: {...}
}

?

4.3 模塊的動態注冊

在模塊創建之后,可以使用store.registerModule方法來注冊模塊。

store.registerModule('myModule', {// ...
});

依然的,可以通過store.state.myModule來獲取模塊的狀態。

可以使用store.unregisterModule(moduleName)來動態的卸載模塊,但是這種方法對于靜態模塊是無效的(即在創建store時聲明的模塊)。

5 含有vuex的項目的結構

5.1 應該遵循的規則

  • 1. 應用層級的狀態都應該集中在store中

  • 2. 提交 mutation 是更改狀態state的唯一方式,并且這個過程是同步的。

  • 3. 異步的操作應該都放在action里面

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/247429.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/247429.shtml
英文地址,請注明出處:http://en.pswp.cn/news/247429.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue中通過第三方代理解決跨域問題

最近在學node&#xff0c;遇到了跨域的問題&#xff0c;來記錄下方法 首頁服務端的框架是通過express-generator 搭建起來的 npm install -g express-generator 具體接下來的細節不多說&#xff0c;今天主要說跨域 的問題 左側為服務端項目結構&#xff0c;www為可執行文件&am…

使用V-chart時配置踩過的一些坑

如何配置圖表信息 echart的配置項可謂是相當的海量&#xff0c;能不看就不看。而v-chart對其進行了不少的簡化&#xff0c;所以我們想要自定義一個圖表時&#xff0c;最好按照以下步驟來檢查&#xff1a; 圖表私有屬性 v-chart每一個圖表都有自己獨有的設置項&#xff0c;想…

ZDOzMRVAOq

11 轉載于:https://www.cnblogs.com/wc529065/p/11212226.html

vue 出現Elements in iteration expect to have 'v-bind:key' directives

是由于eslint檢測出現bug 解決方法有兩種 v-for 后添加 :keyitem <li v-for"item in list" :key"item"> 在build處關閉eslint檢測 ...(config.dev.useEslint ? [createLintingRule()] : []),

requestAnimationFram

window.requestAnimationFrame() 告訴瀏覽器——你希望執行一個動畫&#xff0c;并且要求瀏覽器在下次重繪之前調用指定的回調函數更新動畫。該方法需要傳入一個回調函數作為參數&#xff0c;該回調函數會在瀏覽器下一次重繪之前執行 注意&#xff1a;若你想在瀏覽器下次重繪之…

vue/return-in-computed-property Enforce that a return statement is present in computed property

此規則強制return語句在computed屬性中得完整存在。 <script> export default {computed: {/* ? GOOD */foo () {if (this.bar) {return this.baz} else {return this.baf}},bar: function () {return false},/* ? BAD */baz () {if (this.baf) {return this.baf}},ba…

vue-cli3 一直運行 /sockjs-node/info?t= 解決方案

首先 sockjs-node 是一個JavaScript庫&#xff0c;提供跨瀏覽器JavaScript的API&#xff0c;創建了一個低延遲、全雙工的瀏覽器和web服務器之間通信通道。 服務端&#xff1a;sockjs-node&#xff08;https://github.com/sockjs/sockjs-node&#xff09; 客戶端&#xff1a;so…

Java生鮮電商平臺-生鮮供應鏈(采購管理)

Java生鮮電商平臺-生鮮供應鏈(采購管理) 在生鮮供應鏈系統中采購中心這一模塊&#xff0c;它是電商公司管理采購的模塊&#xff0c;包含供應商管理&#xff0c;采購訂單管理&#xff0c;采購商品管理&#xff0c;在該模塊中采購訂單是采購中心的核心模塊。在其他的比如供應商的…

鏈式調用setTimeout()與setInterval()的區別

使用 setTimeout()和 setInterval()創建的定時器可以用于實現有趣且有用的功能。執行時機是不能保證的&#xff0c;因為在頁面的生命周期中&#xff0c;不同時間可能有其他代碼在控制 JavaScript 進程。在頁面下載完后的代碼運行、事件處理程序、Ajax 回調函數都必須使用同樣的…

Multiple Dispatch

今天在看文章的時候遇到了multiple dispatch這個術語。看看了wiki&#xff0c;寫得云里霧里。最后搜了搜資料&#xff0c;基本上搞清楚了。 multiple dispatch的混淆之處在于其和object system結合在一起。當然wiki上寫得很清楚&#xff1a;“a function or method can be dyna…

如何讓Element UI的Message消息提示每次只彈出一個

Element UI的Message消息提示是點擊一次觸發一次的。在開發的時候經常會作為一些校驗提示&#xff0c;但是公司的測試人員在進行測試時會一直點&#xff0c;然后就會出現如下圖的情況。雖然客戶使用的時候一般來說不會出現這種情況&#xff08;畢竟客戶不會閑著沒事一直點點點&…

jsp頭文件的內容/response.setHeader

轉載的&#xff01;&#xff01;&#xff01;做一個記錄!!!! response.setHeader 是用來設置返回頁面的頭 meta 信息, 使用時 response.setHeader( name, contect ); meta是用來在HTML文檔中模擬HTTP協議的響應頭報文。meta 標簽用于網頁的<head>與</head>中 1、&l…

css3實現科技感的呼吸燈效果

呼吸燈效果是一種常見的燈光效果&#xff0c;比如網頁的按鈕&#xff0c;現實生活中比如電腦的開機按鈕。 使用CSS3的animation方法可以實現很多迷人的網頁動畫特效。 使用CSS3 配合box-shadow即可實現類似的效果 樣式代碼如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18…

WIX(20121031) 應用設置默認變量

花了了好長時間找到的 這樣可以將變量信息定義到wxs中&#xff0c;方便應用 <?xml version"1.0" encoding"UTF-8"?> <?define ProductName"Wix CY"?> <Wix xmlns"http://schemas.microsoft.com/wix/2006/wi">&l…

百度Echarts折線圖tooltip里數據添加單位

option {title: {text: 折線圖堆疊},tooltip: {trigger: axis,//在這里設置formatter: {a0}:{c0}萬},legend: {data:[郵件營銷,聯盟廣告,視頻廣告,直接訪問,搜索引擎]},grid: {left: 3%,right: 4%,bottom: 3%,containLabel: true},toolbox: {feature: {saveAsImage: {}}},xAxi…

VUE組件 之 Drawer 抽屜

一、源碼地址 https://github.com/imxiaoer/DrawerForVue 二、效果圖 三、具體代碼 drawer.vue <template><div class"drawer"><div :class"maskClass" click"closeByMask"></div><div :class"mainClass"…

什么是基金凈值、單位凈值、累計凈值

基金知識-單位凈值和累計凈值 一投資者問&#xff1a;單位凈值和累計凈值分別指什么&#xff1f;如何通過這兩個值來評定一個基金&#xff1f; 景順長城基金管理有限公司答&#xff1a;基金資產凈值是在某一時點上&#xff0c;基金資產的總市值扣除負債后的余額&#xff0c;代表…

Java生鮮電商平臺-用戶管理的架構與實戰

Java生鮮電商平臺-用戶管理的架構與實戰 在電商后臺中&#xff0c;用戶管理是運營人員管理用戶的模塊。這里的用戶區別于運營人員&#xff0c;會在權限的角色管理中分別闡述。這里的用戶包含平臺的一般用戶&#xff0c;會員用戶等。本文將分享一下用戶管理模塊的設計心得。在設…

vue+Element-ui實現分頁效果

當我們向后臺請求大量數據的時候&#xff0c;并要在頁面展示出來&#xff0c;請求的數據可能上百條數據或者更多的時候&#xff0c;并不想在一個頁面展示&#xff0c;這就需要使用分頁功能來去完成了。 1.本次所使用的是vue2.0element-ui實現一個分頁功能&#xff0c;element-…