vuex的常見問題

習(xí)慣養(yǎng)成很容易谓晌,戒掉卻很難!2系印筐赔!

什么是Vuex?

Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式钻趋。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài)川陆。

Vuex解決了什么問題剂习?

解決兩個(gè)問題

多個(gè)組件依賴于同一狀態(tài)時(shí)蛮位,對(duì)于多層嵌套的組件的傳參將會(huì)非常繁瑣,并且對(duì)于兄弟組件間的狀態(tài)傳遞無能為力鳞绕。

來自不同組件的行為需要變更同一狀態(tài)失仁。以往采用父子組件直接引用或者通過事件來變更和同步狀態(tài)的多份拷貝。以上的這些模式非常脆弱们何,通常會(huì)導(dǎo)致無法維護(hù)的代碼萄焦。

什么時(shí)候用Vuex?

當(dāng)項(xiàng)目遇到以下兩種場景時(shí)

多個(gè)組件依賴于同一狀態(tài)時(shí)冤竹。

來自不同組件的行為需要變更同一狀態(tài)拂封。

Vuex的5個(gè)核心屬性是什么?

分別是 state鹦蠕、getter冒签、mutation、action钟病、module 萧恕。

Vuex中狀態(tài)儲(chǔ)存在哪里,怎么改變它肠阱?

存儲(chǔ)在state中票唆,改變Vuex中的狀態(tài)的唯一途徑就是顯式地提交 (commit) mutation。

Vuex中狀態(tài)是對(duì)象屹徘,使用時(shí)候注意什么走趋?

因?yàn)閷?duì)象是引用類型,復(fù)制后改變屬性還是會(huì)影響原始數(shù)據(jù)噪伊,這樣會(huì)改變state里面的狀態(tài)簿煌,是不允許典挑,所以先用深度克隆復(fù)制對(duì)象,再修改啦吧。

怎么在組件中批量使用Vuex的state狀態(tài)您觉?

使用mapState輔助函數(shù), 利用對(duì)象展開運(yùn)算符將state混入computed對(duì)象中

import {mapState} from 'vuex'

export default{

????computed:{

????????...mapState(['price','number'])

????}

}

Vuex中要從state派生一些狀態(tài)出來,且多個(gè)組件使用它授滓,該怎么做琳水?

使用getter屬性,相當(dāng)Vue中的計(jì)算屬性computed般堆,只有原狀態(tài)改變派生狀態(tài)才會(huì)改變在孝。

getter接收兩個(gè)參數(shù),第一個(gè)是state淮摔,第二個(gè)是getters(可以用來訪問其他getter)私沮。

const store = newVuex.Store({

????state: {

????????price: 10,

????????number: 10,

????????discount: 0.7,

????},

????getters: {

????????total: state => {

????????????return state.price * state.number

????????},

????????discountTotal: (state, getters) => {

????????????return state.discount * getters.total

????????}

????},

});

然后在組件中可以用計(jì)算屬性computed通過this.$store.getters.total這樣來訪問這些派生轉(zhuǎn)態(tài)。

computed: {

????total() {

????????return this.$store.getters.total

????},

????discountTotal() {

????????return this.$store.getters.discountTotal

????}

}

怎么通過getter來實(shí)現(xiàn)在組件內(nèi)可以通過特定條件來獲取state的狀態(tài)和橙?

通過讓getter返回一個(gè)函數(shù)仔燕,來實(shí)現(xiàn)給getter傳參。然后通過參數(shù)來進(jìn)行判斷從而獲取state中滿足要求的狀態(tài)魔招。

const store = new Vuex.Store({

????state: {

????????todos: [

????????????{ id: 1, text: '...', done: true},

????????????{ id: 2, text: '...', done: false}

????????]

????},

????getters: {

????????getTodoById: (state) => (id) =>{

????????????return state.todos.find(todo => todo.id === id)

????????}

????},

});

然后在組件中可以用計(jì)算屬性computed通過this.$store.getters.getTodoById(2)這樣來訪問這些派生轉(zhuǎn)態(tài)晰搀。

computed: {

????getTodoById() {

????????return this.$store.getters.getTodoById

????},

}

mounted(){

????console.log(this.getTodoById(2).done)//false

}

怎么在組件中批量使用Vuex的getter屬性

使用mapGetters輔助函數(shù), 利用對(duì)象展開運(yùn)算符將getter混入computed 對(duì)象中

import {mapGetters} from 'vuex'

export default{

????computed:{

????????...mapGetters(['total','discountTotal'])

????}

}

怎么在組件中批量給Vuex的getter屬性取別名并使用

使用mapGetters輔助函數(shù), 利用對(duì)象展開運(yùn)算符將getter混入computed 對(duì)象中

import {mapGetters} from 'vuex'

export default{

????computed:{

????????...mapGetters(

????????????myTotal:'total',

????????????myDiscountTotal:'discountTotal',

????????)

????}

}

在Vuex的state中有個(gè)狀態(tài)number表示貨物數(shù)量,在組件怎么改變它办斑。

首先要在mutations中注冊一個(gè)mutation

const store = new Vuex.Store({

????state: {

????????number: 10,

????},

????mutations: {

????????SET_NUMBER(state,data){

????????????state.number=data;

????????}

????},

});

在組件中使用this.$store.commit提交mutation外恕,改變number

this.$store.commit('SET_NUMBER',10)

在Vuex中使用mutation要注意什么。

mutation 必須是同步函數(shù)

在組件中多次提交同一個(gè)mutation乡翅,怎么寫使用更方便鳞疲。

使用mapMutations輔助函數(shù),在組件中這么使用

methods:{

????...mapMutations({

????????setNumber:'SET_NUMBER',

????})

}

然后調(diào)用this.setNumber(10)相當(dāng)調(diào)用this.$store.commit('SET_NUMBER',10)

Vuex中action和mutation有什么區(qū)別?

action 提交的是 mutation蠕蚜,而不是直接變更狀態(tài)尚洽。mutation可以直接變更狀態(tài)。

action 可以包含任意異步操作波势。mutation只能是同步操作翎朱。

提交方式不同,action 是用this.$store.dispatch('ACTION_NAME',data)來提交尺铣。mutation是用this.$store.commit('SET_NUMBER',10)來提交拴曲。

接收參數(shù)不同,mutation第一個(gè)參數(shù)是state凛忿,而action第一個(gè)參數(shù)是context澈灼,其包含了

{

????state,????? // 等同于 `store.state`,若在模塊中則為局部狀態(tài)

????rootState,? // 等同于 `store.state`,只存在于模塊中

????commit,???? // 等同于 `store.commit`

????dispatch,?? // 等同于 `store.dispatch`

????getters,??? // 等同于 `store.getters`

????rootGetters // 等同于 `store.getters`叁熔,只存在于模塊中

}

Vuex中action和mutation有什么相同點(diǎn)委乌?

??? 第二參數(shù)都可以接收外部提交時(shí)傳來的參數(shù)。

this.$store.dispatch('ACTION_NAME',data)和this.$store.commit('SET_NUMBER',10)

在組件中多次提交同一個(gè)action荣回,怎么寫使用更方便遭贸。

使用mapActions輔助函數(shù),在組件中這么使用

methods:{

????...mapActions({

????????setNumber:'SET_NUMBER',

????})

}

然后調(diào)用this.setNumber(10)相當(dāng)調(diào)用this.$store.dispatch('SET_NUMBER',10)

Vuex中action通常是異步的,那么如何知道action什么時(shí)候結(jié)束呢心软?

在action函數(shù)中返回Promise壕吹,然后再提交時(shí)候用then處理

actions:{

????SET_NUMBER_A({commit},data){

????????return newPromise((resolve,reject) =>{

????????????setTimeout(() =>{

????????????????commit('SET_NUMBER',10)

????????????},2000)

????????}

????????)

????}

}

this.$store.dispatch('SET_NUMBER_A').then(() => {

??// ...

})

Vuex中有兩個(gè)action,分別是actionA和actionB删铃,其內(nèi)都是異步操作耳贬,在actionB要提交actionA,需在actionA處理結(jié)束再處理其它操作猎唁,怎么實(shí)現(xiàn)咒劲?

利用ES6的async和await來實(shí)現(xiàn)。

actions:{

????async actionA({commit}){

????????//...

????},

????async actionB({dispatch}){

????????await dispatch ('actionA')//等待actionA完成

????????// ...

????}

}

有用過Vuex模塊嗎诫隅,為什么要使用腐魂,怎么使用。

有阎肝,因?yàn)槭褂脝我粻顟B(tài)樹挤渔,應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對(duì)象。當(dāng)應(yīng)用變得非常復(fù)雜時(shí)风题,store 對(duì)象就有可能變得相當(dāng)臃腫。所以將 store 分割成模塊(module)嫉父。每個(gè)模塊擁有自己的 state沛硅、mutations、actions绕辖、getters摇肌,甚至是嵌套子模塊,從上至下進(jìn)行同樣方式的分割仪际。

在module文件新建moduleA.js和moduleB.js文件围小。在文件中寫入

const state={

????//...

}

const getters={

????//...

}

const mutations={

????//...

}

const actions={

????//...

}

export default{

????state,

????getters,

????mutations,

????actions

}

然后再index.js引入模塊

import Vue from 'vue';

import Vuex from 'vuex';

Vue.use(Vuex);

import moduleA from './module/moduleA'

import moduleB from './module/moduleB'

const store = newVuex.Store({

????modules:{

????????moduleA,

????????moduleB

????}

})

export default store

在模塊中,getter和mutation接收的第一個(gè)參數(shù)state树碱,是全局的還是模塊的肯适?

第一個(gè)參數(shù)state是模塊的state,也就是局部的state成榜。

在模塊中框舔,getter和mutation和action中怎么訪問全局的state和getter

在getter中可以通過第三個(gè)參數(shù)rootState訪問到全局的state,可以通過第四個(gè)參數(shù)rootGetters訪問到全局的getter。

在mutation中不可以訪問全局的satat和getter,只能訪問到局部的state刘绣。

在action中第一個(gè)參數(shù)context中的context.rootState訪問到全局的state樱溉,context.rootGetters訪問到全局的getter。

在組件中怎么訪問Vuex模塊中的getter和state,怎么提交mutation和action纬凤?

直接通過this.$store.getters和this.$store.state來訪問模塊中的getter和state福贞。

直接通過this.$store.commit('mutationA',data)提交模塊中的mutation。

直接通過this.$store.dispatch('actionA,data')提交模塊中的action停士。

用過Vuex模塊的命名空間嗎肚医?為什么使用,怎么使用向瓷。

??? 默認(rèn)情況下肠套,模塊內(nèi)部的action、mutation和getter是注冊在全局命名空間猖任,如果多個(gè)模塊中action你稚、mutation的命名是一樣的,那么提交mutation朱躺、action時(shí)刁赖,將會(huì)觸發(fā)所有模塊中命名相同的mutation、action长搀。

這樣有太多的耦合宇弛,如果要使你的模塊具有更高的封裝度和復(fù)用性,你可以通過添加namespaced: true 的方式使其成為帶命名空間的模塊源请。

export default{

????namespaced: true,

????state,

????getters,

????mutations,

????actions

}

怎么在帶命名空間的模塊內(nèi)提交全局的mutation和action枪芒?

??? 將 { root: true } 作為第三參數(shù)傳給 dispatch 或 commit 即可。

this.$store.dispatch('actionA', null, { root: true})

this.$store.commit('mutationA', null, { root: true})

怎么在帶命名空間的模塊內(nèi)注冊全局的action谁尸?

actions: {

????actionA: {

????????root: true,

????????handler (context, data) { ... }

????}

??}

組件中怎么提交modules中的moduleA中的mutationA舅踪?

this.$store.commit('moduleA/mutationA',data)

怎么使用mapState,mapGetters良蛮,mapActions和mapMutations這些函數(shù)來綁定帶命名空間的模塊抽碌?

首先使用createNamespacedHelpers創(chuàng)建基于某個(gè)命名空間輔助函數(shù)

import { createNamespacedHelpers } from 'vuex';

const { mapState, mapActions } = createNamespacedHelpers('moduleA');

export default{

????computed: {

????????// 在 `module/moduleA` 中查找

????????...mapState({

????????????a: state => state.a,

????????????b: state => state.b

????????})

????},

????methods: {

????????// 在 `module/moduleA` 中查找

????????...mapActions([

????????????'actionA',

????????????'actionB'

????????])

????}

}

Vuex插件有用過嗎?怎么用簡單介紹一下决瞳?

Vuex插件就是一個(gè)函數(shù)货徙,它接收 store 作為唯一參數(shù)。在Vuex.Store構(gòu)造器選項(xiàng)plugins引入皮胡。

在store/plugin.js文件中寫入

export default function createPlugin(param){

????returnstore =>{

????????//...

????}

}

然后在store/index.js文件中寫入

import createPlugin from './plugin.js'

const plugin = createPlugin()

const store = newVuex.Store({

??// ...

??plugins: [myPlugin]

})

在Vuex插件中怎么監(jiān)聽組件中提交mutation和action痴颊?

用Vuex.Store的實(shí)例方法subscribe監(jiān)聽組件中提交mutation

用Vuex.Store的實(shí)例方法subscribeAction監(jiān)聽組件中提交action

在store/plugin.js文件中寫入

export default function createPlugin(param) {

????returnstore => {

????????store.subscribe((mutation, state) => {

????????????console.log(mutation.type)//是那個(gè)mutation

????????????console.log(mutation.payload)

????????????console.log(state)

????????})

????????// store.subscribeAction((action, state) => {

????????//???? console.log(action.type)//是那個(gè)action

????????//???? console.log(action.payload)//提交action的參數(shù)

????????// })

????????store.subscribeAction({

????????????before: (action, state) => {//提交action之前

????????????????console.log(`before action ${action.type}`)

????????????},

????????????after: (action, state) => {//提交action之后

????????????????console.log(`after action ${action.type}`)

????????????}

????????})

????}

}

然后在store/index.js文件中寫入

import createPlugin from './plugin.js'

const plugin = createPlugin()

const store = newVuex.Store({

??// ...

??plugins: [myPlugin]

})

在v-model上怎么用Vuex中state的值?

需要通過computed計(jì)算屬性來轉(zhuǎn)換胸囱。

<input v-model="message">

// ...

computed: {

????message: {

????????get () {

????????????return this.$store.state.message

????????},

????????set (value) {

????????????this.$store.commit('updateMessage', value)

????????}

????}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末祷舀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌裳扯,老刑警劉巖抛丽,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異饰豺,居然都是意外死亡亿鲜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門冤吨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒿柳,“玉大人,你說我怎么就攤上這事漩蟆±萏剑” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵怠李,是天一觀的道長圾叼。 經(jīng)常有香客問我,道長捺癞,這世上最難降的妖魔是什么夷蚊? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮髓介,結(jié)果婚禮上惕鼓,老公的妹妹穿的比我還像新娘。我一直安慰自己唐础,他們只是感情好箱歧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著彻犁,像睡著了一般叫胁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汞幢,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音微谓,去河邊找鬼森篷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛豺型,可吹牛的內(nèi)容都是我干的仲智。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼姻氨,長吁一口氣:“原來是場噩夢啊……” “哼钓辆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤前联,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后似嗤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啸臀,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烁落,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年乘粒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡熊痴,死狀恐怖巾陕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梯刚,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布京革,位于F島的核電站来惧,受9級(jí)特大地震影響屿脐,放射性物質(zhì)發(fā)生泄漏西疤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一狐蜕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乖寒,春花似錦、人聲如沸院溺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽珍逸。三九已至逐虚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谆膳,已是汗流浹背叭爱。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漱病,地道東北人买雾。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像杨帽,于是被迫代替她去往敵國和親漓穿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345