Vuex是一个专门为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以可预测的方式发生改变
10.1安装
vue add vuex
10.2起始
State:将应用全局状态定义在state中
state{
isLogin:false
}
Mutation:修改state只能通过mutation
mutations:{
login(state){
state.isLogin = true
}
logout(state){
state.isLogin = false
}
}
10.3获取和修改状态
使用store.state获取状态
<button @click="login" v-if="!$store.$state.isLogin">登录</button>
<button @click="logout" v-else>登出</button>
修改状态只能通store.dispatch(mutation)
this.$store.commit('login')
this.$store.commit('logout')
Action类似于mutation,不同在于Action可以提交的是mutation,而不是直接变更状态
Action可以包含任意异步操作
login({commit},username){
return new Promise((resolve,reject)=>{
setTimeOut(()=>{
if(username==='admin'){
commit('login')
resolve()
}else{
reject()
}
})
})
}
派发动作
this.$store.dispatch('login','admin').then(()=>{
this.$router.push(this.$route.query.redirect)
}).catch(()=>{
alert("用户名或密码错误")
})
10.4模块化
使用modules定义多个子模块利于组件的复杂状态
import user from './user'
export default new Vuex.Store({
modules:{
user
}
})
移动端先前登录状态相关代码到user.js
export default{
namespaced:true,//避免命名冲突
//...
}
访问方式响应变化
<button @click="login" v-if="!$store.state.user.isLogin">登录</button>
this.$store.dispatch('user/login','admin').then(()=>{
const redirect = this.$route.query.redirect||'/'
this.$router.push(redirect)
}).catch(()=>{
alert("用户名或者密码错误")
})
mapState()/mapMutation()/mapAction()
通过这些映射方法可以让大家少敲几个字,避免对$store直接访问
import {mapState} from 'vuex'
computed:{
...mapState('user',['isLogin'])
}
<button @click="login" v-if="!isLogin">登录</button>
action相关修改
import {mapActions} from 'vuex'
methods:{
login(){
this['user/login']('admin').then(...)
}
...mapActions(['user/login','user/logout'])
}
Getter
可以使用getters从store的state派生出一些状态
export default{
namespaced:true,
state:{
isLogin:false,
username:''//用户名
},
mutations:{
setUsername(state,username){
state.username = username
}
},
getters:{
welcome:state=>{
return state.username+',欢迎回来'
}
},
actions:{
login({commit},username){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(username==='admin'){
commit('setUsername',username)
resolve()
}else{
reject()
}
},1000)
})
}
}
}
10.5严格模式
严格模式下,无论何时发生了状态变更且不是由mutation函数引起,将会抛出错误。这能保证所有的状态变更都能被调试工具追踪到,开启严格模式strict
const store = new Vuex.Store({
// ...
strict:true
})
10.6插件
Vuex的store接受plugins选项,这个选项暴露出每次mutation的钩子。Vuex插件就是一个函数,它接收store作为唯一参数:
const myPlugin = store = >{
//当store初始化后调用
}
注册插件:
const store = new Vuex.Store({
//...
plugins:[myPlugin]
})
范例:实现登录状态持久化,store/plugins/persist.js
export default store=>{
if(localStorage){
const user = JSON.parse(localStorage.getItem('user'))
if(user){
store.commit('user/login')
store.commit('user/setUsername',user.username)
}
}
Store.subscribe((mutation,state)=>{
if(mutation.type.startsWith('user/')){
localStorage.setItem('user',JSON.stringify(state.user))
}else if(mutation.type==='user/logout'){
localStorage.removeItem('user')
}
})
}