权限验证对于后台管理系统必不可少,不同的权限对应不同的路由,同时侧边栏也需要根据权限不同,异步生成.下面是登录和权限验证的思路.
登录触发登录事件 ($store.dispatch参考下面的Vuex)
this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
this.$router.push({ path: '/' }); //登录成功之后重定向到首页
}).catch(err => {
this.$message.error(err); //登录失败提示错误
});
Vuex
Vuex是为Vue.js应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态,并且用相应的规则保证状态以一种可预测的方式发生变化.
new Vue({
// state
data () {
return {
count: 0
}
},
// view
template: `
{{ count }}
`,
// actions
methods: {
increment () {
this.count++
}
}
})
状态自管理应用包含以下几个部分:
state: 驱动应用的数据源;
view: 以声明方式将state映射到视图
actions: 响应在view上的用户输入导致状态变化
Vuex应用的核心是store(仓库).''store"基本上是一个容器,它包含着应用中大部分的状态(state).Vuex和单纯的全局对象有两点不同:
创建一个store(示例)
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
可以通过store.state来获取状态对象,通过store.commit方法触发状态变更:
store.commit('increment')
console.log(store.state.count) // -> 1
dispatch: 含有异步操作,例如向后台提交数据,写法: this.$store.dispatch('action方法名',值)
commit: 同步操作,写法:this.$store.commit('mutations方法名',值)
由于store中的状态是响应式的,在组件中调用store中的状态仅需在计算属性中返回就行.触发变化
仅仅是在组件的methods中提交mutation(具体参考vuex相关文档)
action:
LoginByUsername({ commit }, userInfo) {
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
loginByUsername(username, userInfo.password).then(response => {
const data = response.data
Cookies.set('Token', response.data.token) //登录成功后将token存储在cookie之中
commit('SET_TOKEN', data.token)
resolve()
}).catch(error => {
reject(error)
});
});
}
登录成功后服务端返回一个token(token是一个能唯一标示用户身份的一个key),然后将
token存储在本地的cookie中(或者localstorage)
获取用户信息
用户登录成功后在全局钩子router.beforeEach中拦截路由,判断是否已获得token,获得token之后我们就要去获取用户的基本信息
//router.beforeEach
if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(res => { // 拉取user_info
const roles = res.data.role;
next();//resolve 钩子
})
store.getter:Vuex允许在store中定义"getter"(可以认为是store的计算属性),getter的返回值会根据依赖被缓存
起来,当依赖值发生改变才会重新计算.
Getter 接受state作为第一个参数:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
通过属性访问
Getter会暴露为store.getters对象.你可以以属性的形式访问这些值
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
Getter可以接受其他getter作为第二个参数
getters: {
// ...
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
store.getters.doneTodosCount // -> 1
可以在其他组件中使用它:
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
通过方法访问
可以让getter返回一个函数,实现给getter传参
getters: {
// ...
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
getter在通过方法访问时,每次进行调用,不会缓存结果
mapGetters辅助函数
mapGetters将store中的getter映射到局部计算属性:
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
Module
因为使用单一状态树,所有状态集中在一个比较大的对象中(store对象会变臃肿)
Vuex将store分割成模块(module),每个模块有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
Vuex暂时就用这么多,剩下的下回再说