一、创建仓库
通过脚手架创建全家桶项目的时候,已经在项目中添加了Vuex选项。创建好项目后src目录下面会有一个store文件夹,该文件夹下有一个名为index.js的文件,文件中的代码就是仓库中的业务。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
二、将store注入Vue对象
将store引入到main.js文件中,注入vue对象后,在项目中任意组件都能直接调用。
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 五大核心对象
state:存放的仓库数据。
getters:相当于计算属性。
mutations:存放的函数,相当于组件中的methods,修改仓库数据的唯一方案,通过mutations来进行。
actions:存放的基本都是异步函数,所有的请求都可以交给actions来管理。
modules:模块化。目前的index.js称为主仓库,还可以被拆分很多子仓库。
state:index.js中的state主要用来存放主仓库的数据。
state中的数据不能互相访问。
export default new Vuex.Store({
state: {
//表达式
username:"xiaowang",
//数组
users:[
{id:1,name:"xiaowang"},
{id:2,name:"xiaozhang"}
],
//对象
student:{
id:1,age:20,gender:"男",name:"王二"
},
//错误示例
username:"xiaowang",
newName:username
},
})
getters:在store仓库中每一个计算属性都可以接受到一个state数据,但是不能通过 this 来相互调用。
export default new Vuex.Store({
state: {
username:"xiaowang",
users:[
{id:1,name:"xiaowang"},
{id:2,name:"xiaozhang"}
],
student:{
id:1,age:20,gender:"男",name:"王二"
}
},
getters:{
// 所有计算属性,都默认会接受state
fullName(state){
return state.username + "中国人"
}
}
})
mutations:mutations里面存放的都是同步函数,一般不写异步函数。每个函数都可以默认接受state仓库数据,修改仓库数据操作state参数。修改state数据的唯一方案就是通过mutations。
export default new Vuex.Store({
state: {
username:"xiaowang",
users:[
{id:1,name:"xiaowang"},
{id:2,name:"xiaozhang"}
],
student:{
id:1,age:20,gender:"男",name:"王二"
}
},
getters:{
// 所有计算属性,都默认会接受state
fullName(state){
return state.username + "中国人"
}
},
mutations: {
// mutations每个函数都可以默认接受state仓库数据
increment(state){
state.count++
},
decrement(state){
state.count--
}
}
})
actions:actions存放异步函数,一般用于管理异步请求。
export default new Vuex.Store({
state: {
username:"xiaowang",
users:[
{id:1,name:"xiaowang"},
{id:2,name:"xiaozhang"}
],
student:{
id:1,age:20,gender:"男",name:"王二"
}
},
getters:{
// 所有计算属性,都默认会接受state
fullName(state){
return state.username + "中国人"
}
},
mutations: {
// mutations每个函数都可以默认接受state仓库数据
increment(state){
state.count++
},
decrement(state){
state.count--
}
},
actions: {
asyncChangeCount(context,val){
// context表示整个仓库
// context.state 才能获取到仓库数据
console.log(val);
setTimeout(() => {
context.state.count+=val
}, 2000);
}
},
})
可以接受第二个参数,传递用户的自定义参数,页面里执行actions里面的函数需要通过 dispatch 来调用。
this.$store.dispatch("asyncChangeCount",10)
5. modules:将主仓库拆分为很多子仓库,用于不同的业务模块。
在store文件夹下面创建modules文件夹用于存放子仓库的数据模块
—- userModule.js(用户模块)
—- permissionsModule.js(权限模块)
注意
namespaced:true必须加上,代表开启命名空间,默认会将文件导入模块作为命名空间名字。
子仓库不需要new Vuex.Store(),因为子仓库只是将主仓库拆分出来,不需要重复创建。
export default {
// 开启命名空间,默认会将文件名字作为仓库名字
namespaced:true,
state:{
tableData:[
{
id: 1,
name: "小王",
age: 25,
dept: "研发部",
bir: "2021-09-08",
time: "2022-01-09",
edit:false
},
{
id: 2,
name: "小张",
age: 20,
dept: "研发部",
bir: "2021-07-08",
time: "2021-08-09",
edit:false
},
]
},
mutations:{
},
actions:{
}
}
在主仓库index.js中引入子仓库
import userModule from "./modules/userModule"
import permissionsModule from "./modules/permissionsModule"
export default new Vuex.Store({
modules: {
userModule,
permissionsModule
}
})
页面组件中使用子仓库数据
要获取子仓库的数据,需要createNamespacedHelpers函数来指定仓库名字,这样才能获取指定仓库的数据。命名空间的作用就是隔离了数据。
<script>
import {createNamespacedHelpers} from "vuex"
const {mapState} = createNamespacedHelpers("userModule")
export default {
computed:{
...mapState(["tableData"])
}
}
</script>
一个页面组件引入多个子仓库
当遇到一个页面需要引入多个模块,不同的命名空间时,我们需要mapState函数来设置别名。
<script>
import {createNamespacedHelpers} from "vuex"
const {mapState:mapUserState,mapMutations:mapUserMutations} = createNamespacedHelpers("userModule")
const {mapState:mapPermissionsState,mapMutations:mapPermissionsMutations} = createNamespacedHelpers("permissionsModule")
export default {
methods:{
...mapUserMutations(["changeTableData"]),
},
computed:{
...mapUserState(["tableData"]),
...mapPermissionsState(["permissionsData"])
}
};
</script>
注意
如果不是在组件中调用Vuex仓库数据,我们需要使用$store来处理。
调用mutations方法
$store.commit("userInfoModule/getUserInfo")
调用actions的方法
$store.dispatch("userInfoModule/asyncGetUserInfo")