W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
對于每個大項(xiàng)目來說,使用狀態(tài)樹 (store) 管理狀態(tài) (state) 十分有必要。這就是為什么 Nuxt.js 內(nèi)核實(shí)現(xiàn)了 Vuex。
Nuxt.js 會嘗試找到應(yīng)用根目錄下的 store 目錄,如果該目錄存在,它將做以下的事情:
Nuxt.js 支持兩種使用 store 的方式,你可以擇一使用:
無論使用那種模式,您的state的值應(yīng)該始終是function,為了避免返回引用類型,會導(dǎo)致多個實(shí)例相互影響。
Nuxt.js允許您擁有一個 store 目錄,其中包含與模塊對應(yīng)的每個文件。
首先,只需將狀態(tài)導(dǎo)出為 函數(shù),將變量和操作作為 store/index.js 中的對象導(dǎo)出:
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
然后,您可以擁有 store/todos.js 文件:
export const state = () => ({
list: []
})
export const mutations = {
add (state, text) {
state.list.push({
text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, todo) {
todo.done = !todo.done
}
}
Vuex將如下創(chuàng)建:
new Vuex.Store({
state: () => ({
counter: 0
}),
mutations: {
increment (state) {
state.counter++
}
},
modules: {
todos: {
namespaced: true,
state: () => ({
list: []
}),
mutations: {
add (state, { text }) {
state.list.push({
text,
done: false
})
},
remove (state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle (state, { todo }) {
todo.done = !todo.done
}
}
}
}
})
在您的 pages/todos.vue 中,使用 todos 模塊:
<template>
<ul>
<li v-for="todo in todos">
<input type="checkbox" :checked="todo.done" @change="toggle(todo)">
<span :class="{ done: todo.done }">{{ todo.text }}</span>
</li>
<li><input placeholder="What needs to be done?" @keyup.enter="addTodo"></li>
</ul>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
todos () {
return this.$store.state.todos.list
}
},
methods: {
addTodo (e) {
this.$store.commit('todos/add', e.target.value)
e.target.value = ''
},
...mapMutations({
toggle: 'todos/toggle'
})
}
}
</script>
<style>
.done {
text-decoration: line-through;
}
</style>
模塊方法也適用于頂級定義,而無需在 store 目錄中實(shí)現(xiàn)子目錄
示例:您創(chuàng)建文件 store/state.js 并添加以下內(nèi)容
export default () => ({
counter: 0
})
相應(yīng)的可以在文件夾中添加 store/mutations.js
export default {
increment (state) {
state.counter++
}
}
您可以將模塊文件分解為單獨(dú)的文件:state.js,actions.js,mutations.js和getters.js。如果您使用index.js來維護(hù)state,getters,actions和mutations,同時具有單個單獨(dú)的操作文件,那么仍然可以正確識別該文件。
注意:在使用拆分文件模塊時,必須記住使用箭頭函數(shù)功能, this 在詞法上可用。詞法范圍this意味著它總是指向引用箭頭函數(shù)的所有者。如果未包含箭頭函數(shù),那么this將是未定義的(undefined)。解決方案是使用 "normal" 功能,該功能會將this指向自己的作用域,因此可以使用。
您可以將其他插件添加到store(在模塊模式下),將其放入store/index.js文件中:
import myPlugin from 'myPlugin'
export const plugins = [ myPlugin ]
export const state = () => ({
counter: 0
})
export const mutations = {
increment (state) {
state.counter++
}
}
有關(guān)插件的更多信息: Vuex 文檔.
fetch 方法會在渲染頁面前被調(diào)用,作用是填充狀態(tài)樹 (store) 數(shù)據(jù),與 asyncData 方法類似,不同的是它不會設(shè)置組件的數(shù)據(jù)。
關(guān)于 fetch 方法的更多信息,請參考 頁面 fetch 方法API。
如果在狀態(tài)樹中指定了 nuxtServerInit 方法,Nuxt.js 調(diào)用它的時候會將頁面的上下文對象作為第2個參數(shù)傳給它(服務(wù)端調(diào)用時才會醬紫喲)。當(dāng)我們想將服務(wù)端的一些數(shù)據(jù)傳到客戶端時,這個方法是灰常好用的。
舉個例子,假設(shè)我們服務(wù)端的會話狀態(tài)樹里可以通過 req.session.user 來訪問當(dāng)前登錄的用戶。將該登錄用戶信息傳給客戶端的狀態(tài)樹,我們只需更新 store/index.js 如下:
actions: {
nuxtServerInit ({ commit }, { req }) {
if (req.session.user) {
commit('user', req.session.user)
}
}
}
如果你使用_狀態(tài)樹模塊化_的模式,只有主模塊(即 store/index.js)適用設(shè)置該方法(其他模塊設(shè)置了也不會被調(diào)用)。
這時context被賦予nuxtServerInit作為第二個參數(shù),它與asyncData或fetch方法相同。
nuxtServerInit 方法接收的上下文對象和 fetch 的一樣,但不包括 context.redirect() 和 context.error()。
注意:異步nuxtServerInit操作必須返回Promise來通知nuxt服務(wù)器等待它們。
actions: {
async nuxtServerInit({ dispatch }) {
await dispatch('core/load')
}
}
默認(rèn)情況下,在開發(fā)模式下啟用嚴(yán)格模式,在生產(chǎn)模式下關(guān)閉模式。要在dev中禁用嚴(yán)格模式,請遵循以下示例。
export const strict = false
此功能已經(jīng)棄用,將在Nuxt 3中刪除。
要使用經(jīng)典模式創(chuàng)建Vuex,我們應(yīng)該創(chuàng)建store/index.js到處返回Vuex實(shí)例的方法的文件:
import Vuex from 'vuex'
const createStore = () => {
return new Vuex.Store({
strict: false,
state: () => ({
counter: 0
}),
mutations: {
increment (state) {
state.counter++
}
}
})
}
export default createStore
我們不需要安裝,因?yàn)閂uex由Nuxt.js提供。
我們現(xiàn)在可以在我們的組件中使用this.$store:
<template>
<button @click="$store.commit('increment')">{{ $store.state.counter }}</button>
</template>
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: