什么是vuex
vue的一个状态管理器,用来集中管理共享的数据,适合数据共享多的项目,如果只是简单的通讯,无需使用vuex
核心概念
state:定义存贮数据的仓库 ,组件可通过this.$store.state 或mapState访问,想要改变store的值 只能通过mutation
//vuex
state = {
userInfo:'',
token:''
}
//组件
import { mapState } from 'vuex'
computed: {
...mapState(['userInfo','token']) // 映射 this.userInfo为 store.state.count 解构法是最常用的 这样不仅可以用mapState,组件内也可以自定义其他的computed 其他写法参考vuex文档
}
getter:获取 store 值,可认为是 store 的计算属性,可通过this.$store.getter 或mapGetters访问
//vuex
getters:{
userInfo:(state) => state.userInfo,
token: (state) => state.token
}
//组件
import { mapGetters} from 'vuex'
computed: {
...mapGetter(['userInfo','token']) // 映射 this.count 为 store.state.count 解构法是最常用的 这样不仅可以用mapGetter,组件内也可以自定义其他的computed 其他写法参考vuex文档
mutation:提供了用来改变 store值的方法(同步),为什么会设计成同步,因为mutation是直接改变store值,vue对操作进行了记录,如果是异步无法追踪改变.可通过this.$store.commit('mutation名称',参数)或者mapMutations调用
//vuex
mutations:{
SET_USER_INFO: (state, userInfo) => {
state.userInfo = userInfo
},
SET_TOKEN: (state,token) => {
state.token = token
}
}
//组件
import { mapMutations } from 'vuex'
methods: {
...mapMutation({setUserInfo:'SET_USER_INFO'}), // 将this.setUserInfo映射成this.$store.commit('increment')这种是最常用的 这样不仅可以用mapMutation,组件内也可以自定义其他的methods其他写法参考vuex文档
...mapMutation(['SET_TOKEN']),//如果不需要改名字 也可以是这种写法
}
或者this.$store.commit('SET_USER_INFO',{userInfo:xxx})
action:异步调用函数执行mutation,进而改变 store 值,可通过 this.$store.dispatch或mapActions访问
//vuex
actions:{
login({ commit }, userInfo){
const { username, password } = userInfo
return userApi.login({ username: username.trim(), password }).then(res => {
if (res) {
commit('SET_TOKEN', res.data)
setToken(res.data)
} else {
commit('SET_TOKEN', null)
setToken('')
}
})
}
}
//组件
import { mapActions} from 'vuex'
methods:{
...mapActions['login'] //这种写法不好传参, 如果需要传参的话 可以用this.$store.dispatch('login',{name:'xxx'})
}
modules:模块,如果项目中需要维护的共享状态过多,所有数据写在一个页面内难以维护,可以根据页面或者其他维度拆分成模块,每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块,最后在入口通过...解构引入
//文件夹的划分
store/modules //模块文件夹
store/modules/user.js //user模块
store/modules/settings.js //setting模块
store/index.js //入口文件
//user.js
const state = {userName:'xxx'} //属于当前模块的state
const getters = {}
const mutations = {}
const actions = {}
export default { //最后导出
namespaced: true, //需要特别注意 如果namespaced设置为true之后 当前模块就成为带命名空间的模块 模块内所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名
state,
mutations,
actions
}
//index.js
import user from './modules/user' //导入
const store = new Vuex.Store({
modules: {
user
}
})
export default store //导出
//组件
import {mapState} from 'vuex'
computed:{
...mapState['user/userName'] //因为user模块设置了namespaced 所以user模块内的getter action state等访问的时候都要以user模块为路径
}
或者this.$store.user.state
使用
1.yarn add vuex //安装vuex
2.import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(vuex) //vue中使用基于vue的组件需要调用Vue.use
3.const store = new Vuex.Store({ //创建vuex实例
state: {},
mutation: {},
actions: {},
modules: {},
getters: {}
})
4.window.$vue = new Vue({ //挂载
el: '#app',
store,
render: h => h(App)
})