安裝vuex依賴
npm i vuex -S
導(dǎo)入vuex 包
import Vuex from 'vuex'
Vue.use(Vuex)
創(chuàng)建 store 對(duì)象
const store=new Vuex.Store({
// state 中存放的就是全局共享的數(shù)據(jù)
state:{count:0}
})
將 store 對(duì)象掛載到 Vue 實(shí)例中
new Vue({
el:'#app',
render:h => h(app),
router,
//將創(chuàng)建的共享數(shù)據(jù)對(duì)象,掛載到 Vue 實(shí)例中
//所有的組件,就可以直接從 store 中獲取全局的數(shù)據(jù)了
store
})
組件訪問 State 中數(shù)據(jù)的第一種方式
this.$store.state.全局?jǐn)?shù)據(jù)名稱
//如果在模板中訪問 不需要寫this
組件訪問 State 中數(shù)據(jù)的第二種方式
//1.從 vuex 中按需導(dǎo)入 mapState 函數(shù)
import {mapState} from 'vuex'
通過此函數(shù)將當(dāng)前組件需要的全局?jǐn)?shù)據(jù),映射為當(dāng)前組件的computed計(jì)算屬性
//2.將全局?jǐn)?shù)據(jù) 映射為當(dāng)前組件的計(jì)算屬性
computed:{
...mapState(['count'])
}
在模板調(diào)用直接寫 count
Mutation
注意:在組件中引入使用vuex全局?jǐn)?shù)據(jù)時(shí),不要直接修改vuex里的原始數(shù)據(jù)
Mutation用于變更 Store中的數(shù)據(jù)
1.只能通過mutation變更Store數(shù)據(jù),不可以直接操作Store中的數(shù)據(jù)
2.通過這種方式操作起來雖然繁瑣一些,但是可以集中監(jiān)控所有數(shù)據(jù)變化
//定義 Mutations
const store = new Vuex.Store({
state:{
count : 0
},
mutations : {
add(state) {
//變更狀態(tài)
state.count++
}
}
})
//使用mutations
methods:{
fn(){
//觸發(fā) mutations 的第一種方式
//commit 的作用就是 調(diào)用某個(gè) mutation 函數(shù)
this.$store.commit('add')
}
}
調(diào)用 mutations 并且 傳遞參數(shù)
//定義 Mutations
const store = new Vuex.Store({
state:{
count : 0
},
mutations : {
add(state,step) {
//變更狀態(tài)
state.count += step
}
}
})
//使用mutations
methods:{
fn(){
//調(diào)用 commit 函數(shù)時(shí) 攜帶參數(shù)
this.$store.commit('add',3)
}
}
提交 mutation 的另一種方式是直接使用包含 type 屬性的對(duì)象
this.store.commit({
type: 'increment',
amount: 10
})
action
如果需要異步變更數(shù)據(jù) 就需要先在組件中使用 $store.dispatch('fn',type)調(diào)用 actions,actions 執(zhí)行完異步操作或得到數(shù)據(jù)后 再使用 cxt.commit 調(diào)用 mutations里的方法更改數(shù)據(jù)
actions:{
fn(cxt,type){
//第一個(gè)參數(shù)是執(zhí)行上下文 類似與this 第二個(gè)參數(shù)是傳參
//actions 需要執(zhí)行異步修改數(shù)據(jù)時(shí)
settimeout(()=>{
let data = 5
cxt.commit('getData',data)
},1000)
},
mutations:{
getData(state,data){
state.data = data
}
}
}
getters
getters 類似于計(jì)算屬性
getter 的返回值會(huì)根據(jù)它的依賴被緩存起來砾赔,且只有當(dāng)它的依賴值發(fā)生了改變才會(huì)被重新計(jì)算。
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
使用時(shí)直接
$store.getters.函數(shù)名
modules 模塊
當(dāng)我們開發(fā)中大型項(xiàng)目時(shí) 會(huì)有相當(dāng)多的數(shù)據(jù)需要傳遞時(shí) 就需要考慮模塊化
//首先在配置 new Vuex.Store實(shí)例的文件中 引入 拆分后的 模塊
import user from '@/store/user'
//之后在 new Vuex.Store實(shí)例的modules中配置
new Vue.Store({
state:{},
actions:{},
mutations:{},
getters:{},
modules:{
user
}
})
注意 分模塊 哪怕已經(jīng)拆分成一個(gè)個(gè)的js文件也需要配置 namespaced:true 命名空間
namespaced這是用于解決不同模塊的命名沖突問題
let user = {
namespaced:true,
state: {
userName: '華子',
},
actions: {},
}
export default user
vuex中的映射函數(shù) (輔助函數(shù))
當(dāng)一個(gè)組件需要獲取多個(gè)狀態(tài)時(shí)候,將這些狀態(tài)都聲明為計(jì)算屬性會(huì)有些重復(fù)和冗余今缚。為了解決這個(gè)問題摇肌,我們可以使用 mapState 輔助函數(shù)幫助我們生成計(jì)算屬性歧蒋,讓你少按幾次鍵
//首先按需引入
import {mapState,mapActions,mapMutations,mapGetters} from 'vuex'
//mapState與mapGetters寫在computed中 mapActions與mapMutations寫在methods中
//都需要寫在最上層
export default {
computed: {
//通過展開運(yùn)算符 可以和別的計(jì)算屬性 混用
...mapState({
userName: (state) => state.user.userName,
}),
...mapGetters({
data: 'user/data',
})
},
//計(jì)算屬性直接 {{userName}}使用即可
methods: {
//在組件中引入映射函數(shù)的方法
...mapActions({
changeNum:'user/changeNum'
}),
...mapMutations({
changeUserName:'user/changeUserName'
}),
...mapMutations(['user/changeUserName',xx,xxx]),
//在組件的自定義函數(shù)內(nèi)調(diào)用 映射函數(shù) 的方法
change(){
this.changeUserName('劉德華')
},
change(){
this['user/changeUserName']('劉德華')
},
changenum(){
this.changeNum(666)
}
},
};
直接在模板中使用映射函數(shù)的方法
<button @click="changeUserName('劉德華')"> 點(diǎn)擊改名 </button>
<button @click="changeNum(666)"> 點(diǎn)擊1s后更改數(shù)字 </button>