Vue项目中,路由守卫用于在导航之前进行权限检查。通过beforeEach和afterEach钩子函数,可实现如身份验证和页面加载状态管理。
网络请求通常使用axios库,通过封装API模块来管理HTTP请求和响应。
全局用户信息可以通过Vuex进行管理,Vuex是Vue.js的状态管理模式,能够在整个应用中共享和管理用户状态,包括登录信息、权限和用户偏好。
-
路由守卫:
// src/main.js import Vue from "vue"; import App from "./App"; import store from "./store"; import router from "./router"; import { initRouterController } from "./router/globalController"; const renderAppHandle = async () => { // 初始化用户登录状态 await store.dispatch("initAuthriozation"); // 注册全局路由 initRouterController({ router, store }); new Vue({ router, store, render: (h) => h(App), }).$mount("#app"); }; renderAppHandle();// src/router/globalController.js import { services } from "@/service"; import reporter from "@/lib/reporter"; import qs from "qs"; export function initRouterController({ router, store }) { // 判断是否有无登录 router.beforeEach((to, from, next) => { const { noAuth = false, title = "" } = to.meta; window.document.title = title; const token = window.localStorage.getItem("token"); if (noAuth) { next(); return; } if (token) { next(); } else { next({ name: "login" }); } }); router.afterEach((to, from) => {}); }// src/router/index.js import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter); const router = new VueRouter({ routes: [ { path: "/", component: () => import("@/views/login/index"), }, { path: "/login", name: "login", component: () => import("@/views/login/index"), meta: { noAuth: true, title: "登录" }, }, ], }); export default router; -
网络请求
// src/lib/request.js import axios from "axios"; import store from "@/store"; import qs from "qs"; // 可以设置 BaseURL 做开发代理 const request = axios.create({ headers: { post: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", }, "X-Requested-With": "XMLHttpRequest", }, timeout: 60 * 1000, // 设置一分钟过期 responseType: "json", }); // 请求发送前拦截器 request.interceptors.request.use( (config) => { const token = store.getters.token; if (token) { config.headers.Authorization = token; } if (config.method === "get") { config.paramsSerializer = function (params) { return qs.stringify(params, { arrayFormat: "repeat" }); }; } return config; }, (err) => { console.error(err); } ); // 请求返回时处理 request.interceptors.response.use( (res) => { const resData = res.data; if (["blob", "arraybuffer"].includes(res.config.responseType)) { return resData; } const { data, errCode, statusCode = 404, message = "数据请求失败", } = resData || {}; // 在这里做一些对响应码判断,并做相应处理逻辑 }, (err) => { if (err.response) { // err.response.status; // err.response; } else { // "non-response"; } return Promise.reject(err); } ); export default request; -
全局用户信息
// src/store/modules/authriozation.js import service from "@/service"; import router from "@/router"; export default { state: { token: "", userInfo: null, }, mutations: { SET_TOKEN(state, token) { state.token = token; }, SET_USERINFO(state, userInfo) { state.userInfo = userInfo; }, }, actions: { // 初始化 async initAuthriozation({ commit, getters, dispatch }) { const token = window.localStorage.getItem('token'); const userInfo = (() => { let str = window.localStorage.getItem('userInfo'); let res try { res = JSON.parse(str) } catch (error) { res = null } return res; })(); if(token) { commit('SET_TOKEN', token); } else { dispatch('logout'); return; } if(userInfo) { commit('SET_TOKEN', token); } else { dispatch('getUserInfo'); } }, // 登录 async login({ commit }, { username, password }) { let token; try { // src/service/authriozation.js: login 登录 token = await service.authriozation.login({ username, password }); } catch { console.error("登录失败"); return; } commit("SET_TOKEN", token); window.localStorage.setItem("token", token); }, // 获取用户信息 async getUserInfo({ commit }) { let userInfo; try { // src/service/authriozation.js: getUserInfo 获取用户信息 userInfo = await service.authriozation.getUserInfo(); } catch { console.error("获取用户信息失败"); return; } commit("SET_USERINFO", userInfo); window.localStorage.setItem("userInfo", JSON.stringify(userInfo)); }, // 退出登录 logout({ commit }) { commit("SET_TOKEN", ""); commit("SET_USERINFO", null); window.localStorage.removeItem("token"); window.localStorage.removeItem("userInfo"); // src/service/authriozation.js: logout 退出登录 service.authriozation.logout(); router.push({ name: 'login' }); }, }, getters: { token: (state) => state.token, userInfo: (state) => state.userInfo, }, }; -
角色路由
不同角色的权限路由不同,一般在登录后获取,并添加路由。
import router from '@/router'; // 假设请求返回的是类似如下路由数据 const roleRoutes = [ { path: '/about', name 'about', component: 'pages/about/index.vue' } ]; // 添加到VueRouter roleRoutes.forEach(roleRoute => { roleRoute.component = () => import(`@/${roleRoute.component}`); router.addRoute(roleRoute); }); -
微信登录(后端处理)
- 先获取 token
axios .get(`https://api.weixin.qq.com/cgi-bin/token`, { params: { grant_type: "client_credential", // 微信公众平台 - 设置 - 开发设置 appid: "AppID", secret: "AppSecret", }, }) .then(({ expires_in, access_token }) => { // access_token: 获取到的凭证 // expires_in: 凭证有效时间,单位:秒。目前是7200秒之内的值。 }); - 生成登录二维码
axios .get(`https://api.weixin.qq.com/cgi-bin/qrcode/create`, { params: { access_token: "access_token", }, }) .then(({ key, ticket }) => { // ticket: 用于获取登录二维码 // key: 用于检验登录状态 }); // 二维码图片链接 function getQrcode() { if (!ticket) return; const qrcode = `https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=${ticket}`; // 检验登录状态 // 超过一分钟未扫码登录重新生成二维码 let time = 60; const intervalId = setInterval(() => { checkoutLogin(intervalId, --time); }, 1000); } - 检验二维码是否过期
// 检验登录状态 function checkoutLogin(intervalId, time) { // 超过一分钟未扫码登录重新生成二维码 if (0 === time) { clearInterval(intervalId); getQrcode(); } // 调接口判断是否已经登录 // 如果已经登录 clearInterval(intervalId); window.localStorage.setItem('token', token); }
- 先获取 token