nuxt踩坑之Vuex狀態(tài)樹(shù)的模塊方式使用詳解
初次看到這個(gè)模塊方式,感覺(jué)很是新奇,之前的vuex狀態(tài)樹(shù)使用方法用的也有些膩了,就想來(lái)實(shí)踐一發(fā)新的東西
廢話不多說(shuō),直接進(jìn)入正題
Vuex狀態(tài)樹(shù)-模塊方式官方文檔解讀
狀態(tài)樹(shù)還可以拆分成為模塊,store 目錄下的每個(gè) .js 文件會(huì)被轉(zhuǎn)換成為狀態(tài)樹(shù)指定命名的子模塊
- 這句話啊,看了半天,我都沒(méi)繞出來(lái)。之前一直用的是store目錄下文件為:index.js、state.js、mutations.js、actions.js。后三個(gè)是index.js的子模塊,你說(shuō)這每個(gè)js文件都是一個(gè)模塊?懵逼一分鐘
- 繼續(xù)往下:使用狀態(tài)樹(shù)模塊化的方式,store/index.js 不需要返回 Vuex.Store 實(shí)例,而應(yīng)該直接將 state、mutations 和 actions 暴露出來(lái)。 到這里我雖然還懵逼著,但是轉(zhuǎn)念一想,nuxt還有這操作,都不用我們自己辛辛苦苦寫export default store = () => new Vuex.Store({}) 了,倒也真的省事兒呢
- 還是繼續(xù)看例子吧,官方給的這個(gè),看了一遍沒(méi)看懂(笨小孩的世界真滴難),你這index.js不是Vuex默認(rèn)的store文件么,再來(lái)一todos.js,同樣暴露出去的對(duì)象,不應(yīng)該是index.js同級(jí)的么
- 重點(diǎn)來(lái)了,看不會(huì)不要緊,照貓畫虎我還是會(huì)滴~
照貓畫虎
// store/index.js
export const state = () => ({
num: 0
})
export const mutations = {
increment (state) {
state.num ++
},
decrement (state) {
state.num --
}
}
// store/plus.js
export const state = () => ({
plusNum: 1
})
export const mutations = {
plus (state) {
state.plusNum ++
}
}
// store/minus.js
export const state = () => ({
minusNum: 10
})
export const mutations = {
minus (state) {
state.minusNum --
}
}
// pages/store.vue
<template>
<section class="container">
<table>
<tr>
<td colspan=4>vuex狀態(tài)樹(shù)使用</td>
</tr>
<tr>
<td>頁(yè)內(nèi)數(shù)據(jù)</td>
<td>index.js</td>
<td>plus.js</td>
<td>minus.js</td>
</tr>
<tr>
<td>{{ count }}</td>
<td>{{ $store.state.num }}</td>
<td>{{ $store.state.plus.plusNum }}</td>
<td>{{ $store.state.minus.minusNum }}</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</section>
</template>
跑一下,??!報(bào)錯(cuò)了,我說(shuō)同學(xué)們啊,我寫的真的沒(méi)有錯(cuò)?。?!
好吧,報(bào)錯(cuò)內(nèi)容:[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
意思是我客戶端和vue SSR生成的DOM不一樣,客戶端不也是SSR生成的,這是個(gè)問(wèn)題,有知道的大佬,希望可以告訴我。
不過(guò)這個(gè)問(wèn)題我倒是解決了,雖然不知道問(wèn)什么-_-!,把那一大堆的tr標(biāo)簽都放到tbody里面就OK了
跑起來(lái),沒(méi)問(wèn)題,按示例的寫法,這樣成功拿到了state的數(shù)據(jù)
接著試試mutation的方法
<tr class="mutation-fun">
<td @click="count ++">count ++</td>
<td @click="$store.commit('increment')">increment</td>
<td @click="$store.commit('plus')">plus</td>
<td @click="$store.commit('minus')">minus</td>
</tr>
報(bào)錯(cuò):[vuex] unknown mutation type: plus
修改下:
<tr class="mutation-fun">
<td @click="count ++">count ++</td>
<td @click="$store.commit('increment')">increment</td>
<td @click="$store.commit('plus/plus')">plus/plus</td>
<td @click="$store.commit('minus/minus')">minus/minus</td>
</tr>
搞定~
自己先小結(jié)下這個(gè)模塊怎么用的吧
nuxt很貼心的幫我們省去了返回Vuex實(shí)例的代碼,我們可以不用去寫了
只有store文件夾下的index.js是一級(jí)的vuex狀態(tài),其他的js文件都是二級(jí)的狀態(tài)樹(shù)。(能不能有三級(jí)的我不知道,不過(guò)感覺(jué)沒(méi)必要,哈哈哈?。。?br />
每個(gè)狀態(tài)樹(shù)文件都可以包含state,mutation,action
使用二級(jí)狀態(tài)樹(shù)的state用: $store.state.文件名.變量名
使用二級(jí)狀態(tài)樹(shù)的mutation用: $store.commit(‘文件名/變量名')
使用二級(jí)狀態(tài)樹(shù)的action用: $store.dispatch(‘文件名/變量名')
官方示例沒(méi)有提到的
二級(jí)狀態(tài)樹(shù)能調(diào)用一級(jí)狀態(tài)樹(shù)的state和mutation以及action嗎?
我們來(lái)給plus.js增加一個(gè)修改index.js中的state的方法plusIndex
export const state = () => ({
plusNum: 1
})
export const mutations = {
plus (state) {
state.plusNum ++
},
plusIndex (state) {
state.num ++
console.log('點(diǎn)擊遞增index的num')
}
}
去試著調(diào)用了一下,文本打印出來(lái)了,也沒(méi)有報(bào)錯(cuò),但是完全獲取不到index中的num哇~~
這次聰明點(diǎn)兒,我直接把state打印出來(lái):
export const state = () => ({
plusNum: 1
})
export const mutations = {
plus (state) {
state.plusNum ++
},
plusIndex (state) {
console.log('state: ', state)
state.num ++
}
}
跑一下試試: 結(jié)果有點(diǎn)兒讓人想哭:state: {num: NaN, plusNum: 1}。再看看頁(yè)面上index.js對(duì)應(yīng)的num依然是0,這就說(shuō)明我們這里的num不是index.js里的num,而是下面state ‘.'(點(diǎn))出來(lái)的num,并且沒(méi)有給初始值就執(zhí)行了一次 ++ ,所以值為NaN
到這里,我已經(jīng)大概猜測(cè)到了這里的彎彎繞是怎么回事兒了 –> 模塊兒的作用域是本文件內(nèi)。但編程不是靠猜的,要用實(shí)踐證明的才是對(duì)的,下面在深究這個(gè)問(wèn)題
反過(guò)來(lái),一級(jí)狀態(tài)樹(shù)能調(diào)用二級(jí)狀態(tài)樹(shù)的state和mutation以及action嗎?
這里的情況跟上面一樣,既然我們的這個(gè)store是模塊方式生成的,那就要遵循模塊化的規(guī)范,變量作用域只能在文件內(nèi)
通過(guò)模塊化編程規(guī)范來(lái)獲取一級(jí)狀態(tài)樹(shù)的state
先把index.js引過(guò)來(lái),因?yàn)椴环判囊眠^(guò)來(lái)的還是不是原來(lái)那個(gè)index.js,所以把它打印出來(lái)看看
const indexVuex = require('./index.js')
console.log('indexVuex: ', indexVuex)
這下不就炸了嘛,我引過(guò)來(lái)的居然是一個(gè)空的vuex狀態(tài)樹(shù)?。。?nèi)容長(zhǎng)這樣子
{
mutation: {},
modules: {
plus: {
mutation: {},
namespaced: true
},
minus: {
mutation: {},
namespaced: true
}
},
namespaced: true
}
好吧,我這個(gè)用模塊化的方式來(lái)使用其他文件內(nèi)的變量的想法也是泡湯了
最后的讓步,我在組件中調(diào)用狀態(tài)樹(shù)時(shí)再去用二級(jí)狀態(tài)樹(shù)的方法修改一級(jí)狀態(tài)樹(shù)的state,先試試:
// plus.js
export const state = () => ({
plusNum: 1
})
export const mutations = {
plus (state) {
state.plusNum ++
},
plusIndex (state, meio) {
meio ++
console.log('meio: ', meio)
}
}
// 調(diào)用:
<td @click="$store.commit('plus/plusIndex', $store.state.num)">遞增index的num</td>
點(diǎn)擊后,依然沒(méi)能修改index.js中的num,查看打印結(jié)果中一直都是1,也就是說(shuō)我們傳進(jìn)去的是基本數(shù)據(jù)類型的0~~
那修改一下,我們傳進(jìn)去一個(gè)引用數(shù)據(jù)類型的看看可以不
// plus.js
export const state = () => ({
plusNum: 1
})
export const mutations = {
plus (state) {
state.plusNum ++
},
plusIndex (state, meio) {
meio.num ++
console.log('meio: ', meio.num)
}
}
// 調(diào)用:
<td @click="$store.commit('plus/plusIndex', $store.state)">遞增index的num</td>
功夫不負(fù)有心人,終于是成功了,雖然這樣很麻煩,但也起到了效果
這里經(jīng)驗(yàn)證:反過(guò)來(lái)一級(jí)狀態(tài)樹(shù)調(diào)用二級(jí)狀態(tài)樹(shù)也是一樣的,代碼就不貼了
小結(jié)一下
- vuex狀態(tài)樹(shù)的模塊寫法,不同的文件之間不能直接引用
- vuex狀態(tài)樹(shù)使用模塊加載引用,得到的是一組命名空間,而不是最終生成的Vuex模塊文件
- 要通過(guò)b文件修改其他文件的state需要在store外部去修改
最后,小小的STAR下
情境(situation):粗略的看完一遍NUXT的官方文檔,回頭把不太清楚的東西再整理一下,這兒就卡在Vuex狀態(tài)樹(shù)的的模塊寫法上
任務(wù)(task):通過(guò)各種方法弄明白NUXT的Vuex狀態(tài)樹(shù)的模塊寫法是怎么實(shí)現(xiàn)的
行動(dòng)(action):第一步,參照官方示例先讓自己的狀態(tài)樹(shù)能運(yùn)行起來(lái);第二步,與普通寫法的狀態(tài)樹(shù)寫法比較并舉一反三,看看模塊寫法和普通寫法的狀態(tài)樹(shù)在使用上有什么區(qū)別和需要注意的
結(jié)果(result):第一,學(xué)會(huì)了vuex狀態(tài)樹(shù)的模塊寫法和用法;第二,通過(guò)探索store目錄下的不同文件之間是否可以互相引用以及模塊引用來(lái)熟悉模塊方式的寫法和普通方式的區(qū)別,也找到了模塊寫法中修改其他模塊的state的方法;第三,模塊寫法的優(yōu)點(diǎn):寫法簡(jiǎn)單,結(jié)構(gòu)清晰明了,符合現(xiàn)在模塊化開(kāi)發(fā);同文件(模塊)內(nèi)部類似普通寫法,可按業(yè)務(wù)模塊劃分Vuex模塊,提高開(kāi)發(fā)效率;還有一點(diǎn)兒,我覺(jué)得這樣寫省事兒,也好看-,-| 媽媽再也不用擔(dān)心我所有的Vuex都放同一個(gè)文件中,要用時(shí)還得找半天了~~
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
elementui實(shí)現(xiàn)表格自定義排序的示例代碼
本文主要介紹了elementui實(shí)現(xiàn)表格自定義排序的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
解決前端調(diào)用后端接口返回200但數(shù)據(jù)返回的是html標(biāo)簽
這篇文章主要給大家介紹了關(guān)于如何解決前端調(diào)用后端接口返回200但數(shù)據(jù)返回的是html標(biāo)簽的相關(guān)資料,文中通過(guò)圖文將解決的過(guò)程介紹的非常詳細(xì),對(duì)同樣遇到這個(gè)問(wèn)題的朋友具有一定的參考解決價(jià)值,需要的朋友可以參考下2024-05-05
Vue組件設(shè)計(jì)之多列表拖拽交換排序功能實(shí)現(xiàn)
這篇文章主要介紹了Vue組件設(shè)計(jì)之多列表拖拽交換排序,常見(jiàn)的場(chǎng)景有單列表拖拽排序,多列表拖拽交換排序,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05
vuejs響應(yīng)用戶事件(如點(diǎn)擊事件)
本篇文章主要介紹了vuejs響應(yīng)用戶事件(如點(diǎn)擊),通過(guò)vuejs響應(yīng)用戶事件的技巧,具有一定的參考價(jià)值,有興趣的小伙伴們可以參考一下。2017-03-03
解決Vue 通過(guò)下表修改數(shù)組,頁(yè)面不渲染的問(wèn)題
下面小編就為大家分享一篇解決Vue 通過(guò)下表修改數(shù)組,頁(yè)面不渲染的問(wèn)題。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03

