使用vue-element-admin集成方案------登录篇(涉及部分Vuex知识)

   权限验证对于后台管理系统必不可少,不同的权限对应不同的路由,同时侧边栏也需要根据权限不同,异步生成.下面是登录和权限验证的思路.

  •  登录:  前端将账号密码post到服务端进行验证,如果验证通过,服务端返回一个token,拿到token后(将token存入cookie中,保证刷新页面后记住用户的登录状态),根据token再去拉去一个user_info的接口来获取用户详情信息(如用户权限,用户名等等)
  •  权限验证: 通过token获取用户对应的role,根据token再去获取用户对应的role,动态根据用户的role算出对应有权限的路由,通过router.addRoutes动态挂载这些路由.

   登录触发登录事件  ($store.dispatch参考下面的Vuex)

this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
  this.$router.push({ path: '/' }); //登录成功之后重定向到首页
}).catch(err => {
  this.$message.error(err); //登录失败提示错误
});

 Vuex

Vuex是为Vue.js应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态,并且用相应的规则保证状态以一种可预测的方式发生变化.

  • 状态管理模式(举个栗子,简单的Vue计数应用开始)
new Vue({
  // state
  data () {
    return {
      count: 0
    }
  },
  // view
  template: `
    <div>{{ count }}</div>
  `,
  // actions
  methods: {
    increment () {
      this.count++
    }
  }
})

 状态自管理应用包含以下几个部分:

state: 驱动应用的数据源;

view: 以声明方式将state映射到视图

actions: 响应在view上的用户输入导致状态变化

Vuex应用的核心是store(仓库).''store"基本上是一个容器,它包含着应用中大部分的状态(state).Vuex和单纯的全局对象有两点不同:

  • Vuex的状态存储是响应式的.当Vue组件从store中读取状态,如果store中的状态改变,那么响应的组件也会相应的更新.
  • 无法直接改变store中的状态,改变store中的状态需要显式的提交(commit)变化(mutation).这样我们可以方便跟踪每一个状态的变化

创建一个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暂时就用这么多,剩下的下回再说

 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值