Vue预习篇(十)vuex

Vuex
安装
vue add vuex

起始
State
将应用全局状态定义在state中

state: {
	isLogin: false
}

Mutation
修改state只能通过mutation

mutations: {
	login(state) {
		state.isLogin = true
	},
	logout(state) {
		state.isLogin = false
	}
}

获取和修改状态
使用store.state获取状态

<button @click="login" v-if="!store.state.isLogin">登录</button>
<button @click="logout" v-else>登出</button>

修改状态只能通过store.dispatch(mutation)

this.$s-tore.commit('login')
this.$store.commit('logout')

Action
Action类似于mutation,不同在于:

  • Action提交的是mutation,而不是直接变更状态。
  • Action可以包含任意异步操作
login({commit}, username) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			if(username === 'admin') {
				commit('login')
				resolve()
			} else {
				reject()
			}
		}, 1000)
	})
}

派发动作

this.$store.dispatch('login', 'admin').then(() => {
	this.$router.push(this.$route.query.redirect)
}).catch(() => {
	alert('用户名或密码错误')
})

最佳实践
模块化
使用modules定义多个子模块利于组件复杂状态

import user from './user'

export default new Vuex.Store({
	modules: {
		user,
	}
})

移动先前登录状态相关代码到user.js

export default {
	// namespaced: true,	// 避免命名冲突
	// ...
}

访问方式响应变化

// Login.vue
<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(() => {
	store.state.user.isLogin
})

mapState()/mapMutation()/mapAction()
通过这些映射方法可以让大家少敲几个字,避免对$store直接访问。
state相关修改,Login.vue

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: {
		setUername(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)
			})
		}
	}
}

严格模式
严格模式下,无论何时发生了状态变更且不是由mutation函数引起的,将会抛出错误,这能保证所有的状态变更都能被调试工具跟踪到。开启严格模式strict: true

const store = new Vuex.Store({
	// ...
	strict: true
})

插件
Vuex的store接收plugins选项,这个选项暴露出每次mutation的钩子。Vuex插件就是一个函数,它接收store作为唯一参数:

const myPlugin = store => {
	// 当store初始化后调用
}

注册插件:

const store = new Vuex.Store({
	// ...
	plugins: [myPlugin]
})

范例:实现登录状态持久化,store/plugins/persist.js

export default store => {
	// 初始化时从localStorage获取数据
	if(localStorage) {
		const user = JSON.parse(localStorage.getItem('user'))
		if(user) {
			store.commit('user/login')
		}
	}
	// 用户状态发生变化时缓存之
	store.subscribe(muation, state) => {
		if(mutation.type.startsWith('user/')) {
			localStorage.setItem('user', JSON.stringify(state.user))
		} else if(mutation.type === 'user/logout') {
			localStorage.removeItem('user')
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值