一,功能演示:
无后端服务时:
提示信息自动关闭后:
服务端返回401访问无授权时,会跳转到login页面
如果登录错误:
登录成功,跳转回home页面,可以看到相应的用户信息:
查看保存到local storage中的token:
说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
或: https://gitee.com/liuhongdi
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,前、后端项目的代码地址
前端:
https://gitee.com/liuhongdi/jwtweb
后端:
https://gitee.com/liuhongdi/jwtdemo
说明:后端项目的说明请参见:
https://www.cnblogs.com/architectforest/p/15185416.html
三,vue.js安装需要用到的依赖库
1,安装axios
查看当前版本
liuhongdi@lhdpc:/data/vue/demo1$ npm list axios demo1@0.1.0 /data/vue/demo1 └── (empty)
安装
liuhongdi@lhdpc:/data/vue/demo1$ npm install axios -S added 1 package in 6s
查看安装后版本
liuhongdi@lhdpc:/data/vue/demo1$ npm list axios demo1@0.1.0 /data/vue/demo1 └── axios@0.21.1
2,安装element-plus
查看当前版本
liuhongdi@lhdpc:/data/vue/demo1$ npm list element-plus demo1@0.1.0 /data/vue/demo1 └── (empty)
安装
liuhongdi@lhdpc:/data/vue/demo1$ npm install element-plus --save added 15 packages, and changed 4 packages in 10s
查看安装后版本
liuhongdi@lhdpc:/data/vue/demo1$ npm list element-plus demo1@0.1.0 /data/vue/demo1 └── element-plus@1.0.2-beta.71
3,安装vue-router
查看当前版本
liuhongdi@lhdpc:/data/vue/demo1$ npm list vue-router@next demo1@0.1.0 /data/vue/demo1 └── (empty)
安装
liuhongdi@lhdpc:/data/vue/demo1$ npm install vue-router@next --save added 2 packages in 4s
查看安装后版本
liuhongdi@lhdpc:/data/vue/demo1$ npm list vue-router@next demo1@0.1.0 /data/vue/demo1 └── vue-router@4.0.11
四,js代码说明:
1,App.vue
<template> <router-view /> </template> <script> export default { name: ‘App‘, components: { } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
2,main.js
import { createApp } from ‘vue‘ import App from ‘./App.vue‘ import ElementPlus from ‘element-plus‘ import ‘element-plus/lib/theme-chalk/index.css‘ import router from ‘./router/router‘ //element-plus 的中文化 import locale from ‘element-plus/lib/locale/lang/zh-cn‘ //element-plus //设置网页标题 router.beforeEach((to, from, next) => { //路由发生变化修改页面title if (to.meta.title) { document.title = to.meta.title+"--网站名称" } next() }) //启动app const app = createApp(App) app.use(ElementPlus,{locale}) app.use(router) app.mount(‘#app‘)
3,router/router.js
import {createRouter, createWebHashHistory} from ‘vue-router‘; import Home from "../views/Home.vue"; import Login from "../views/Login.vue"; //路由 let routes = [ { path: "/", redirect: ‘/home‘ }, { path: "/login", name: "login",meta:{title:"登录",top:"0"},component: Login, }, { path: "/home", name: "home",meta:{title:"个人页",top:"0"},component: Home, }, ] // Vue-router新版本中,需要使用createRouter来创建路由 export default createRouter({ // 指定路由的模式,此处使用的是hash模式 history: createWebHashHistory(), routes })
4,api/axios.js
import axios from ‘axios‘ import { ElMessage } from "element-plus"; import router from "../router/router" let config = { timeout:10000, }; const _axios = axios.create(config); _axios.interceptors.request.use( function(config) { // Do something before request is sent if (localStorage.getItem(‘token‘)) { config.headers.Authorization = "Bearer "+localStorage.getItem(‘token‘); } return config; }, function(error) { // Do something with request error return Promise.reject(error); } ); // Add a response interceptor _axios.interceptors.response.use( function(response) { let code = response.data.code; if (code == ‘401‘) { //现在跳转去登录 router.push({ path: ‘/login‘ }); } return response; }, function(error) { // Do something with response error if (error.response.status) { //alert(error.response.status); switch (error.response.status) { // 401: 未登录 // 未登录则跳转登录页面,并携带当前页面的路径 // 在登录成功后返回当前页面,这一步需要在登录页操作。 case 401: router.push({ path: ‘/login‘ }); break; // 403 token过期 // 登录过期对用户进行提示 // 清除本地token和清空vuex中token对象 // 跳转登录页面 case 403: ElMessage.error("登录过期,请重新登录"); // 清除token localStorage.removeItem(‘token‘) // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面 setTimeout(() => { router.push({ path: ‘/login‘ }); }, 1000) break; // 404请求不存在 case 404: ElMessage.error("网络请求不存在,404错误"); break; // 500服务端错误 case 500: ElMessage.error("服务端有故障,500错误"); break; // 其他错误,直接抛出错误提示 default: //alert("default:"+error.response.data.message); var tip = ""; if (typeof(error.response.data.message) == "undefined") { //alert(error); tip = error.toString(); } else { tip = error.response.data.message; } ElMessage.error(tip); break; } return Promise.reject(error.response) } } ); /** * get方法,对应get请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */ export function get (url, params) { return new Promise((resolve, reject) => { _axios.get(url, { params: params, }).then(res => { resolve(res.data) }).catch(err => { reject(err.data) }) }) } //post export function postForm (url, params) { //axios.defaults.headers.post[‘Content-Type‘] = ‘multipart/form-data‘; return new Promise((resolve, reject) => { _axios.post(url, params,{headers: { ‘Content-Type‘: ‘application/x-www-form-urlencoded‘, }}) .then(res => { resolve(res.data) }) .catch(err => { console.log("api error:"); console.log(err); //alert(err); reject(err.data) }) }) } //用json格式post提交 export function postJson (url, params) { return new Promise((resolve, reject) => { _axios.post(url, JSON.stringify(params)) .then(res => { resolve(res.data) }) .catch(err => { reject(err.data) }) }) }
5,其他代码可参见gitee
五,查看项目中第三方库的版本
liuhongdi@lhdpc:/data/vue/jwtweb$ npm list jwtweb@0.1.0 /data/vue/jwtweb ├── @vue/cli-plugin-babel@4.5.13 ├── @vue/cli-plugin-eslint@4.5.13 ├── @vue/cli-service@4.5.13 ├── @vue/compiler-sfc@3.2.4 ├── axios@0.21.1 ├── babel-eslint@10.1.0 ├── core-js@3.16.2 ├── element-plus@1.0.2-beta.71 ├── eslint-plugin-vue@7.16.0 ├── eslint@6.8.0 ├── vue-router@4.0.11 └── vue@3.2.4
六,查看vue/cli及node的版本:
liuhongdi@lhdpc:/data/vue/jwtweb$ vue --version @vue/cli 4.5.13 liuhongdi@lhdpc:/data/vue/jwtweb$ node -v v14.17.1
springboot+vue实现前后端分离之前端vue部分(spring boot 2.5.4/vue.js 3.2.4)