简介
Vuex 是 Vue 的状态管理模式+库。使用 Vuex,你可以确保状态变更的明确性和可追踪性,使多人协作开发的大型应用变得更加容易维护和理解。同时,它也能帮助你更好地组织和管理你的应用状态。
Vuex官网:Vuex
Vuex 的核心概念
- state 数据状态
- getters 类似于计算属性,在此对状态进行包装
- mutation
同步更改数据状态,接收一个必传参数state - action
异步更改状态,通过调用mutation方法来间接更改state的状态,接收一个默认参数context(context.ommit('方法名','参数')) - modules 挂载别的模块。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。
在vue中如何使用vuex
安装vuex
yarn add vuex
在Vue实例中挂载Vuex Store
// main.js
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')
创建Vuex Store
在你的项目结构中,创建一个新的文件夹(例如store),并在其中创建一个名为index.js的文件。在这个文件中,你将定义你的Vuex store。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0,
name: '岚'
},
getters: {
},
mutations: {
changeCount(state) {
state.count++
},
changeName(state, newName) {
state.name = newName
}
},
actions: {
changeNameAction(context, newName) {
setTimeout(() => {
context.commit('changeName', newName)
}, 500)
}
},
modules: {
}
})
在组件中使用
可以在Vue组件中通过this.$store来访问Vuex store了。但更常见的做法是使用mapState、mapGetters、mapMutations和mapActions辅助函数来帮助你更简洁地管理状态。
- 组件中获取state中数据的方法:
- 直接使用
$store.state.状态名 - 使用
mapState,用mapState将store中的state映射到组件中...mapState(['状态名'])如果在组件中命名有冲突时可以使用别名...mapState({'组件中使用的别名':'store中的组件名'})
- 在组件中调用getter的方法:
$store.getters.状态名- 使用
mapGetter
- 在组件中调用mutation的方法:
$store.commit('store中的方法名','参数')触发- 使用
mapMutations()
- 在组件中调用action的方法:
$store.dispatch('方法名','参数')触发- 使用
mapActions()
<template>
<div class="about">
<h1>This is an about page</h1>
<p>{{ $store.state.name }} <button @click="changeName('山风')">点我改变name</button> </p>
<button @click="changeC">点我++{{ $store.state.count }} = {{num}}</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
computed: {
...mapState(['name']),
...mapState({num:'count'}),//在组件中使用num就可以访问到store中的count
},
methods: {
...mapMutations(['changeCount']),
...mapActions(['changeNameAction']),
changeName(newName) {
this.changeNameAction(newName)
},
changeC() {
this.changeCount()
}
}
}
</script>
分模块
在store文件夹下,创建一个新的文件夹(例如modules),并在其中创建一个名为name.js的文件。在这个文件中,你将定义你的Module Vuex store。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const nameModule = {
namespaced: true,
state: {
name: '岚'
},
getters: {
},
mutations: {
changeName(state, newName) {
state.name = newName
}
},
actions: {
changeNameAction(context, newName) {
setTimeout(() => {
context.commit('changeName', newName)
}, 500)
}
},
}
export default nameModule
将这个nameModule引入到我们的index中
import Vue from 'vue'
import Vuex from 'vuex'
import nameModule from './modules/name'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0,
},
getters: {
},
mutations: {
changeCount(state){
state.count++
},
},
actions: {
},
modules: {
nameModule
}
})
这时我们在组件中该如何使用呢?
- 对于action,mutation,getters,是在模块中还是在全局里使用方式都相同,但对于state中的状态,模块中的state多一层模块名
$state.state.模块名.状态名(根state中的格式为:$state.state.状态名) - 可以通过开启命名空间(
namespaced:true)来隔离各个模块。开启命名空间后的模块中的getters,mutations,actions的使用方法会发生改变,但不开启命名空间的state的使用方法与开启命名空间的state的使用方法一致。 - 以下是在组件中使用已开启命名空间后的module中的方法以及获取状态的方法:
- ...mapState({状态名: state => state.模块名.状态名})
- ...mapState('模块名',{状态名: state => state.状态名})
- ...mapGetters(['模块名/状态名'])
- ...mapGetters('模块名',['状态名'])
- this.$store.dispatch('模块名/方法名')
<template>
<div class="about">
<h1>This is an about page</h1>
<p>{{ $store.state.nameModule.name }} <button @click="changeName('山风')">点我改变name</button> </p>
<button @click="changeC">点我++{{ $store.state.count }}</button>
</div>
</template>
<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
computed: {
...mapState('nameModule', ['name'])
},
methods: {
...mapMutations(['changeCount']),
...mapActions('nameModule', ['changeNameAction']),
changeName(newName) {
console.log(newName);
this.changeNameAction(newName)
},
changeC() {
this.changeCount()
}
}
}
</script>