簡單說明
什么是vuex,vuex怎么使用,什么場景下適合使用vuex, vuex 文檔中都有介紹。看完文檔之后,都知道vuex的核心有State、Getter、Mutation、Action、Module,也都知道分別都是干嘛的。但是實(shí)際到項(xiàng)目中可能就會(huì)出現(xiàn)不知道怎么動(dòng)手實(shí)際操作了。下面就通過一個(gè)簡單實(shí)例來說下vuex具體如何使用。
分步操作,從安裝到實(shí)例操作。
安裝vuex
安裝vuex有3種方式。其中兩種是在通過 vue create project-name
創(chuàng)建項(xiàng)目時(shí)選擇安裝,如圖所示:
第一種會(huì)把vue-router、vuex、babel、eslint一起安裝。
第二種手動(dòng)選擇安裝,根據(jù)需要選擇性安裝,如圖所示:
第三種就是在創(chuàng)建項(xiàng)目時(shí)選擇default,只會(huì)安裝babel、eslint。創(chuàng)建好項(xiàng)目之后,進(jìn)入到項(xiàng)目,然后安裝vuex。
> cd project-name
> npm install vuex
分步準(zhǔn)備階段
按步驟,一步步來
項(xiàng)目目錄:
由于使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對象。當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store 對象就有可能變得相當(dāng)臃腫。為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個(gè)模塊擁有自己的 state、mutation、action、getter。
而實(shí)際項(xiàng)目也會(huì)分多個(gè)模塊,比如:用戶、訂單等。此實(shí)例中只創(chuàng)建了一個(gè)用戶模塊。
模塊文件
- 在src目錄下創(chuàng)建一個(gè)store目錄,進(jìn)入到store目錄,然后在創(chuàng)建一個(gè)modules目錄,最后user模塊文件user.js
const state = {
//在此處定義組件要用到的屬性值
status: false,
todoList: []
}
const mutations = {
/**
* 此處定義修改狀態(tài)值的函數(shù),注意只能是同步函數(shù)。
* 因?yàn)槿绻钱惒胶瘮?shù),當(dāng) mutation 觸發(fā)的時(shí)候,回調(diào)函數(shù)還沒有被調(diào)用,
* 那么在回調(diào)函數(shù)中進(jìn)行的狀態(tài)的改變就不可追蹤了。
*/
SET_STATUS: (state, status) => {
state.status = status
},
SET_TODOLIST: (state, todos) => {
state.todoList = todos
}
}
const actions = {
/**
* Action 類似于 mutation,不同在于:
* ① Action 提交的是 mutation,而不是直接變更狀態(tài)。
* ② Action 可以包含任意異步操作。
* 最后一個(gè) store.dispatch 在不同模塊中可以觸發(fā)多個(gè) action 函數(shù)了。
*/
login ({ commit }, val) {
const { status } = val
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('SET_STATUS', status)
resolve({ status: status })
}, 100)
})
},
todoList ({ commit }) {
return new Promise((resolve) => {
setTimeout(() => {
commit('SET_TODOLIST', todo)
resolve({ code: 200 })
}, 100)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
總的來說:①state中定義好要用的屬性值;②mutation中定義好操作這些屬性的函數(shù)(同步函數(shù));③action中定義可以提交mutation的函數(shù),可以是異步函數(shù);
getters.js
在store目錄下創(chuàng)建getters文件
如果modules有多個(gè)模塊,那么可以在getters文件中統(tǒng)一的提供供組件中獲取不同模塊中的屬性值。如代碼所示:
const getters = {
//user.js
status: state => state.user.status,
doneTodos: state => {
return state.user.todoList.filter(todo => todo.done)
}
//order.js
payStatus: state => state.order.payStatus
}
export default getters
index.js
在store目錄下創(chuàng)建index文件
導(dǎo)入之前在modules定義的文件和getters文件。導(dǎo)入modules有2種方式:①按照注釋的方式導(dǎo)入;
②按照代碼中現(xiàn)在方式引入使用
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
# improt user from './modules/user'
Vue.use(Vuex)
const modulesFiles = require.context('./modules', true, /\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})
const store = new Vuex.Store({
//user,
modules,
getters
})
export default store
最后在main.js中導(dǎo)入store
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')