后台管理系统 一 登录模块

目录

模板介绍

项目目录

环境变量

登录业务

完成静态组件

vuex

'js-cookie'第三方库

书写api

axios的二次封装

解决代理跨域问题


项目地址

https://gitee.com/childe-jia/background-system.giticon-default.png?t=M4ADhttps://gitee.com/childe-jia/background-system.git

模板介绍

GitHub - PanJiaChen/vue-admin-template: a vue2.0 minimal admin templatea vue2.0 minimal admin template . Contribute to PanJiaChen/vue-admin-template development by creating an account on GitHub.https://github.com/PanJiaChen/vue-admin-template

项目目录

build:inde.jswebpack配置文件【很少修改这个文件】
mock: 数据文件夹【模拟一些假的数据】
node-modules: 项目依赖
public: icon图标 静态页面 静态资源 webpack不会编译这个文件夹
src程序源码
    api: 涉及请求相关的
    assets:放置静态资源(一般是共享的)webpack会进行编译
    component:非路由组件,全局组组件
    icons: svg矢量图
    layout:组件与混入
    router:路由相关
    store vuex
    style:样式
    utils: 公共类库 axios的二次封装
    views: 路由文件夹
 app:根组件
 main 入口文件
 permission:导航守卫
 settings:项目配置项

环境变量

设置webpack配置文件 运行时可以检测环境(webpack对外暴露了 process可以拿到 env为环境变量。设置的值必须VUE_APP开头)

# just a flag
ENV = 'development'

# base api
VUE_APP_BASE_API = '/dev-api'

 分环境加网络请求前缀

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})
  • .env.development 开发
  • .env.production 生产
  • .env.staging 测试
  • process.env读取环境变量
  • 设置文件时值必须以VUE_APP开头

登录业务

完成静态组件

   handleLogin() {
      //验证用户名和密码的规则
      this.$refs.loginForm.validate((valid) => {
        // 符合派发登录接口携带数据
        if (valid) {
          this.loading = true;
          this.$store
            .dispatch("user/login", this.loginForm)
            .then(() => {
              this.$router.push({ path: this.redirect || "/" });
              this.loading = false;
            })
            .catch(() => {
              this.loading = false;
            });
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },

vuex

const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    avatar: ''
  }
}
const state = getDefaultState()
const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  
}
const actions = {
  // user login

  async login({ commit }, userInfo) {
    const { username, password } = userInfo
    let result = await login({ username: username.trim(), password: password })
    if (result.code == 20000) {
      commit('SET_TOKEN', result.data.token)
      setToken(result.data.token)
      return 'ok'
    } else {
      return Promise.reject(new Error('false'))
    }
    // return new Promise((resolve, reject) => {
    //   login({ username: username.trim(), password: password }).then(response => {
    //     const { data } = response
    //     commit('SET_TOKEN', data.token)
    //     setToken(data.token)
    //     resolve()
    //   }).catch(error => {
    //     reject(error)
    //   })
    // })
  },
}
export default {
  namespaced: true,
  state,
  mutations,
  actions
}

'js-cookie'第三方库

下载cookie  
 npm install js-cookie
当前页面引用cookie 
import Cookies from "js-cookie";
cookie在当前的使用
// 写入cookie
Cookies.set('name', 'value')
// 读取
Cookies.get('name') // => 'value'
Cookies.get('nothing') // => undefined
// 读取所有可见的cookie
Cookies.get()
// 删除某项cookie值
Cookies.remove('name')
// 删除存了指定页面path的cookie
Cookies.remove('name', { path: '' }); 
cookie设置过期时间
Cookies.set('key', 'value', { expires: 27 });//创建有效期为27天的cookie
Cookies.set('key', 'value', { expires: 17, path: ''  }); //可以通过配置path,为当前页创建有效期7天的cookie

业务需要在前端进行数据的缓存,到期就删除再进行获取新数据。

前端设置数据定时失效的可以有下面2种方法:
1、当数据较大时,可以利用localstorage,存数据时候写入一个时间,获取的时候再与当前时间进行比较
2、如果数据不超过cookie的限制大小,可以利用cookie比较方便,直接设置有效期即可

利用localstorage实现:步骤
1.存储数据时加上时间戳
在项目开发中,我们可以写一个公用的方法来进行存储的时候加上时间戳

//export抛出
export function setLocalStorageAndTime (key, value) {
 window.localStorage.setItem(key, JSON.stringify({ data: value, time: new Date().getTime() }))
}
存储、
// 有数据再进行存储
 setLocalStorageAndTime('XXX', {name: 'XXX'})
读取、
// 判断是否返回为null或者失效
getLocalStorageAndTime('XXX', 86400000)
获取数据时与当前时间进行比较、

export function getLocalStorageAndTime (key, exp = 86400000) {
 // 获取数据
 let data = window.localStorage.getItem(key)
 if (!data) return null
 let dataObj = JSON.parse(data)
 // 与过期时间比较
 if (new Date().getTime() - dataObj.time > exp) {
  // 过期删除返回null
  removeLocalStorage(key)
  console.log('信息已过期')
  return null
 } else {
  return dataObj.data
 }
}

利用cookie实现

Cookies.set('name', 'value', { expires: 7 }); // 7 天后失效
//官方文档只要设置天数,没有时分秒,这样我们想设置更小单位的时候无法下手,其实也可以设置时间戳来处理时间的,下面这种方式可以设置任意单位的有效期:

let seconds = 10;
let expires = new Date(new Date() * 1 + seconds * 1000);
Cookies.set('username', 'tanggaowei', { expires: expires }); // 10 秒后失效



import Cookies from 'js-cookie'
 
/*
* 设置cookies
* */
export function getCookies (key) {
 return Cookies.get(key)
}
/*
* 设置Cookies
* */
export function setCookies (key, value, expiresTime) {
 let seconds = expiresTime
 let expires = new Date(new Date() * 1 + seconds * 1000)
 return Cookies.set(key, value, { expires: expires })
}
/*
* 移除Cookies
* */
export function removeCookies (key) {
 return Cookies.remove(key)
}

  代码

import Cookies from 'js-cookie'

const TokenKey = 'vue_admin_template_token'

export function getToken() {
  return Cookies.get(TokenKey)
}

export function setToken(token) {
  return Cookies.set(TokenKey, token)
}

export function removeToken() {
  return Cookies.remove(TokenKey)
}

书写api

import request from '@/utils/request'

export function login(data) {
  return request({
    url: '/admin/acl/index/login',
    method: 'post',
    data
  })
}

export function getInfo(token) {
  return request({
    url: '/admin/acl/index/info',
    method: 'get',
    params: { token }
  })
}

export function logout() {
  return request({
    url: '/admin/acl/index/logout',
    method: 'post'
  })
}

axios的二次封装

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

// 请求拦截器,携带的token字段
service.interceptors.request.use(
  config => {
    // do something before request is sent

    if (store.getters.token) {
      // let each request carry token
      // ['X-Token'] is a custom headers key
      // please modify it according to the actual situation
      config.headers['token'] = getToken()
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

//响应拦截器
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    const res = response.data

    // 服务器响应失败
    if (res.code !== 20000 && res.code !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // to re-login
        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
          confirmButtonText: 'Re-Login',
          cancelButtonText: 'Cancel',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      // 成功
      return res
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

解决代理跨域问题

在vue.config.js中 配置devServer

devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    //配置代理
    proxy: {
      "/dev-api": {
        target: "http://gmall-h5-api.atguigu.cn",
        pathRewrite: { "^/dev-api": "" }
      }
    }
  },

退出登录

组件中派发任务

    async logout() {
      await this.$store.dispatch("user/logout");
      this.$router.push(`/login?redirect=${this.$route.fullPath}`);
    },
  },

vuex清除token

 
const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    avatar: ''
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
}

 logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token).then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值