PR做视频需要放网站上,网站建设需要费用,凡科小程序免费制作平台,h5模板素材Vue-element-admin 是一个基于 Vue.js 和 Element UI 的后台管理系统框架#xff0c;提供了丰富的组件和功能#xff0c;可以帮助开发者快速搭建现代化的后台管理系统。 一、基本知识
#xff08;一#xff09;Vue-element-admin 的主要文件和目录 vue-element-admin/ |--… Vue-element-admin 是一个基于 Vue.js 和 Element UI 的后台管理系统框架提供了丰富的组件和功能可以帮助开发者快速搭建现代化的后台管理系统。 一、基本知识
一Vue-element-admin 的主要文件和目录 vue-element-admin/ |-- build/ # 构建相关配置文件 | |-- build.js # 生产环境构建脚本 | |-- check-versions.js # 检查 Node.js 和 npm 版本的脚本 | |-- logo.png # 构建 Logo | |-- utils.js # 构建工具函数 | |-- vue-loader.conf.js # Vue loader 配置 | |-- webpack.base.conf.js # webpack 基础配置 | |-- webpack.dev.conf.js # webpack 开发环境配置 | |-- webpack.prod.conf.js # webpack 生产环境配置 | |-- config/ # 项目配置 | |-- dev.env.js # 开发环境变量配置 | |-- index.js # 项目配置文件 | |-- prod.env.js # 生产环境变量配置 | |-- src/ # 源代码 | |-- api/ # 接口请求相关 | |-- assets/ # 静态资源 | |-- components/ # 全局公用组件 | |-- directive/ # 自定义指令 | |-- icons/ # 图标 | |-- layout/ # 全局布局 | |-- router/ # 路由配置 | |-- store/ # 全局状态管理 | |-- styles/ # 全局样式 | |-- utils/ # 工具函数 | |-- views/ # 页面组件 | |-- App.vue # 入口页面 | |-- main.js # 入口 JS 文件 | |-- permission.js # 路由守卫 文件 | |-- static/ # 静态资源 | |-- .babelrc # Babel 配置 |-- .editorconfig # 编辑器配置 |-- .eslintignore # ESLint 忽略文件配置 |-- .eslintrc.js # ESLint 配置 |-- .gitignore # Git 忽略文件配置 |-- index.html # 入口 HTML 文件 |-- package.json # 项目信息和依赖配置 |-- README.md # 项目说明文档 |-- vue.config.js # Vue CLI 配置 二单点登录系统涉及的文件和概念 **客户端ID和客户端密钥**前端应用和后端应用在与单点登录系统通信时需要提供客户端ID和客户端密钥进行身份验证。**授权码authorization code**单点登录系统验证用户身份成功后生成的一次性授权码用于换取访问令牌和刷新令牌。**访问令牌access token**单点登录系统验证成功后返回给前端应用的令牌用于后续请求时进行身份验证。**刷新令牌refresh token**单点登录系统验证成功后返回给前端应用的令牌用于在访问令牌过期时更新访问令牌。**前端应用使用的SDK或库文件**前端应用需要集成相应的SDK或库文件以便与单点登录系统进行通信。**单点登录系统的API文档**开发人员需要根据API文档了解单点登录系统提供的接口和参数以便正确调用API接口。 二、 前端实现单点登录的基本流程 **设计思路**为了避免code和access_token的泄露所以大部分的和单点登录系统统一认证的交互都放到后端进行前端尽可能的复用原来的代码进行小的改动。整体思路如下 ****1、登录页面–login.vue(修改原login.vue)***用户访问前端应用前端应用将用户重定向到后端登录接口。 templatediv classlogin-containerdiv正在重定向到登录页面.../div/div
/templatescript
export default {created() {const baseUrl process.env.VUE_APP_BASE_API;//重定向到后端的SSOlogin/login接口window.location.href ${baseUrl}/SSOlogin/login;},
};
/scriptstyle scoped
.login-container {display: flex;justify-content: center;align-items: center;height: 100vh;text-align: center;
}
/style****2、 响应页面–callback.vue(新建)***检查后端返回的URLtoken访问链接中是否存在后端返回的token如果存在则调用登录函数user/login进行前端的登录操作调用login函数进行前端的登录目的是将token持久化和存储到VUEX中尽可能少的改动原来的代码。并根据登录结果进行不同的处理。如果没有获取到token则输出错误信息并终止后续逻辑。 templatedivh1Loading.../h1/div
/templatescript
export default {name: Callback,data() {return {};},created() {// 获取 URL 查询参数中的授权码const token this.$route.query.token;// 利用后端传递的token调用login函数进行前端的登录目的是将token持久化和存储到VUEX中尽可能少的改动原来的代码if (token) {this.loading true;this.$store.dispatch(user/login,token).then(() {// 登录成功路由跳转this.$router.push({ path: this.redirect || / });this.loading false;}).catch(() {this.loading false;});} else {console.log(error submit!!);return false;}},
};
/script对应的store/user.js。 3、 数据仓库 store/user.js修改一下原来的Login函数即可。 原Login函数为
//这里在处理登录业务async login({ commit }, userInfo) {//解构出用户名与密码const { username, password } userInfo;let result await login({ username: username.trim(), password: password });if(result.code200){//vuex存储tokencommit(SET_TOKEN,result.data.token);//本地持久化存储tokensetToken(result.data.token);return ok;}else{return Promise.reject(new Error(faile));}},修改后的Login为 // 登录 actionasync login({ commit }, token) {try {// 设置 token 持久化commit(SET_TOKEN, token);// 将 token 值保存在浏览器的本地存储中setToken(token);// 可以根据需要返回其他数据或状态return ok;} catch (error) {// 异常时返回一个被拒绝的 Promise 对象return Promise.reject(error);}},所以修改login函数去掉了使用用户名和密码发送请求到后端接口验证登录完整的代码如下
// 引入需要使用的函数和模块
import { getInfo, logout } from /api/user
import { getToken, setToken, removeToken } from /utils/auth
import { resetRouter } from /router// 定义获取默认状态的函数
const getDefaultState () {return {token: getToken(), // 使用 getToken 函数获取 token 值name: ,avatar: }
}// 定义 Vuex 模块的状态
const state getDefaultState()// 定义 Vuex 模块的变更操作
const mutations {// 重置状态为默认状态RESET_STATE: (state) {Object.assign(state, getDefaultState())},// 设置 tokenSET_TOKEN: (state, token) {state.token token},// 设置用户名SET_NAME: (state, name) {state.name name},// 设置用户头像SET_AVATAR: (state, avatar) {state.avatar avatar}
}// 定义 Vuex 模块的异步操作
const actions {// 用户登录// 登录 actionasync login({ commit }, token) {try {// 设置 tokencommit(SET_TOKEN, token);// 将 token 值保存在浏览器的本地存储中setToken(token);// 可以根据需要返回其他数据或状态return ok;} catch (error) {// 异常时返回一个被拒绝的 Promise 对象return Promise.reject(error);}},async getInfo({ commit, state }) {try {// 发送请求获取用户信息const response await getInfo(state.token)// 如果响应数据不存在说明验证失败if (!response.data) {throw new Error(验证失败请重新登录。)}// 获取用户名和头像const { name, avatar } response.data// 设置用户名commit(SET_NAME, name)// 设置用户头像commit(SET_AVATAR, avatar)// 返回完整的响应对象return response} catch (error) {return Promise.reject(error)}},// 用户注销async logout({ commit, state }) {try {// 发送请求注销用户登录状态await logout(state.token)// 从本地存储中删除 tokenremoveToken()// 重置路由resetRouter()// 重置状态commit(RESET_STATE)} catch (error) {return Promise.reject(error)}},// 重置 token 值async resetToken({ commit }) {try {// 从本地存储中删除 tokenremoveToken()// 重置状态commit(RESET_STATE)} catch (error) {return Promise.reject(error)}}
}// 导出 Vuex 模块
export default {namespaced: true, // 开启命名空间state,mutations,actions
}4、 数据仓库store/user.js引入的函数和模块 为了更清晰的了解整个过程将上面store/user.js引入的函数和模块也贴在下面即 因为 store/user.js中不用再向后端发请求所以api/user.js中就可以把login删掉了。 api/user.js //api/user.js
import request from /api/request/requestexport function getInfo(token) {return request({url: /user/getInfo,method: get,params: { token }})
}export function logout() {return request({url: /user/logout,method: post})
}**utils/auth.js**用于处理用户身份验证 token 的工具函数主要涉及对浏览器 Cookie 的操作。getToken获取用户的身份验证 tokensetToken设置用户的身份验证 tokenremoveToken移除用户的身份验证 token。 //utils/auth.js
import Cookies from js-cookieconst TokenKey vue_admin_template_tokenexport function getToken() {return Cookies.get(TokenKey)
}export function setToken(token) {return Cookies.set(TokenKey, token)
}export function removeToken() {return Cookies.remove(TokenKey)
}5、路由守卫–permission.js修改原来的在每次路由导航之前进行身份验证和权限控制确保用户在正确的身份状态下访问页面并在页面切换后完成进度条的展示。 如果用户已登录且获取了用户信息则直接跳转到目标页面如果用户未登录或获取用户信息失败则跳转至登录页。同时白名单内的页面可以在未登录状态下直接访问。修改配置白名单把callback加进去 注意通过 user/getInfo 获取用户信息 await store.dispatch(‘user/getInfo’)所以****api/user.js 里面要有getInfo函数。 permission.js 完整的代码如下 import router from ./router
import store from ./store
import { Message } from element-ui
import NProgress from nprogress // 引入进度条库
import nprogress/nprogress.css // 引入进度条样式
import { getToken } from /utils/auth // 引入获取 token 的方法
import getPageTitle from /utils/get-page-title // 引入获取页面标题的方法NProgress.configure({ showSpinner: false }) // 配置进度条const whiteList [/login,/callback] // 定义无需登录即可访问的白名单路由router.beforeEach(async(to, from, next) {NProgress.start() // 开始进度条document.title getPageTitle(to.meta.title) // 设置页面标题const hasToken getToken() // 获取 tokenif (hasToken) {if (to.path /login) {// 如果已登录却访问登录页则重定向到首页next({ path: / })NProgress.done() // 完成进度条} else {const hasGetUserInfo store.getters.name // 判断是否已获取用户信息if (hasGetUserInfo) {// 如果已获取则直接进入路由next()} else {try {// 如果未获取则通过 user/getInfo 获取用户信息await store.dispatch(user/getInfo)console.log(获取用户信息)next()} catch (error) {// 如果获取用户信息失败则重置 token 并跳转至登录页await store.dispatch(user/resetToken)Message.error(error || Has Error)next(/login?redirect${to.path})// window.location.href www.baidu.com;NProgress.done()}}}} else {if (whiteList.indexOf(to.path) ! -1) {// 如果在白名单中则直接进入路由next()} else {// 否则跳转至登录页next(/login?redirect${to.path})NProgress.done()}}
})router.afterEach(() {NProgress.done() // 完成进度条
})6、请求拦截器中添加token到请求头和原来一样在请求拦截器中从cookie中获取token并将其添加到请求的头信息中这样可以确保每次请求都带上了token。 import axios from axios
import { MessageBox, Message } from element-ui
import store from /store
import { getToken } from /utils/auth// 创建一个axios实例
const service axios.create({baseURL: process.env.VUE_APP_BASE_API, // 接口的基础路径timeout: 5000 // 请求超时时间
})// 请求拦截器
service.interceptors.request.use(config {// 在请求发送前做一些处理if (store.getters.token) {// 如果有token就在请求头中加上tokenconfig.headers[token] getToken()}return config},error {// 对请求错误做些什么console.log(error)return Promise.reject(error)}
)// 响应拦截器
service.interceptors.response.use(response {// 对响应数据做一些处理这里只返回响应数据中的data部分const res response.data// 如果自定义的响应码不是20000就判断为错误if (res.code ! 20000 res.code ! 200) {// 在页面上显示错误信息Message({message: res.message || Error,type: error,duration: 5 * 1000})if (res.code 50008 || res.code 50012 || res.code 50014) {// 重新登录MessageBox.confirm(您已经登出您可以取消以留在此页面或重新登录, 确认登出, {confirmButtonText: 重新登录,cancelButtonText: 取消,type: warning}).then(() {store.dispatch(user/resetToken).then(() {location.reload()})})}// 返回一个被拒绝的Promise对象用来表示错误return Promise.reject(new Error(res.message || Error))} else {// 如果没有错误就返回响应数据中的data部分return res}},error {// 对响应错误做些什么console.log(err error)Message({message: error.message,type: error,duration: 5 * 1000})return Promise.reject(error)}
)export default service**7、获取用户信息并渲染页面**在需要展示用户信息的地方从cookie中获取用户信息并将其渲染到页面上。