当前位置: 首页 > wzjs >正文

平阳网站建设深圳网页设计

平阳网站建设,深圳网页设计,directadmin备份网站,西部数码网站正在建设中是什么意思目录 登录认证与退出登录登录认证实现步骤第一步、登录路由配置第二步、实现登录页效果第三步、Pinia 管理认证状态第四步、提交登录表单第六步、axios在请求头上添加认证token 退出登录实现步骤第一步、调用接口api方法 logout第二步、pinia 中实现退出功能第三步、触发退出登…

目录

  • 登录认证与退出登录
    • 登录认证实现步骤
      • 第一步、登录路由配置
      • 第二步、实现登录页效果
      • 第三步、Pinia 管理认证状态
      • 第四步、提交登录表单
      • 第六步、axios在请求头上添加认证token
    • 退出登录实现步骤
      • 第一步、调用接口api方法 logout
      • 第二步、pinia 中实现退出功能
      • 第三步、触发退出登录事件

登录认证与退出登录

vue3的登录认证与退出登录

登录认证实现步骤

第一步、登录路由配置

关于 /login 登录组件路由配置:在 src/router/index.ts 新定义一个 fullscreenRoutes 指定全屏显示路由(登录页),不作用到 layout 布局的渲染出口。

import { createRouter, createWebHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'// 扩展 RouteMeta 接口,因为 Vue-Router 的配置路由对象的 meta 属性有限,所以需要扩展
declare module 'vue-router' {interface RouteMeta {title?: string; // 菜单标题icon?: string; // 图标linkTo?: string; // 外链地址cache?: boolean; //是否缓存:true缓存,false不缓存,会将 name 值用于 <keep-alive>的includes上hidden?: boolean; // 是否在菜单中显示:true显示,false隐藏isBreadcrumb?: boolean; // 是否显示到面包屑,默认或true会显示,false不显示。}
}
/***  路由表配置数组(单独抽取,后面扩展后端动态加载)*/
export const dynamicRoutes: RouteRecordRaw[] = [... 省略]
/**
* 全屏显示路由,不作用到 layout 布局渲染出口。
* (后端路由控制:后端配置菜单数据中不需要下面的菜单项)
*/
export const fullscreenRoutes: RouteRecordRaw[] = [{path: '/login',name: 'Login',component: () => import('@/views/auth/login.vue'),meta: {title: '登录',hidden: true,},},
];const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [...dynamicRoutes, ...fullscreenRoutes]
})export default router

第二步、实现登录页效果

  1. 声明登录表单的数据类型

    // 登录信息
    declare interface LoginData {username: string;password: string;
    }
    

vue3的登录认证与退出登录

  1. 实现静态页面,静态页面代码如下,直接使用即可

    <script setup lang="ts">
    import { ref, reactive, toRefs } from 'vue';
    import { isUsername, isPassword } from '@/utils/validate';
    import { useAuthStore } from '@/stores/auth';
    import { useRouter, useRoute } from 'vue-router';const authStore = useAuthStore();const router = useRouter();
    const route = useRoute();const formRef = ref();const state = reactive({loading: false,isRemember: true, // 是否记住密码loginData: {username: '',password: '',} as LoginData
    });const { loading, isRemember, loginData } = {...toRefs(state)};/*** 校验用户名是否合法* @param rule * @param value * @param callback */
    function checkUsername(rule: any, value: string, callback: Function) {if (!value) return callback(new Error('请输入有效帐号/手机号!'));if (!isUsername(value)) return callback(new Error('输入的格式不正确,请重新输入!'));callback(); // 通过
    }
    /*** 校验密码是否合法*/
    function checkPassword(rule: any, value: string, callback: Function) {if(!value) return callback(new Error('请输入有效密码!'));if(!isPassword(value))  return callback(new Error('密码输入错误,请重新输入!'));callback();// 通过
    }// 提交表单
    function submitForm(){}</script><template><div class="login-container"><div class="login-wrap"><img class="lagin-logo" src="@/assets/logo-01.png"/><div class="login-title"> 帐号登录 </div><el-form class="login-form" ref="formRef" :model="loginData" size="large"><el-form-item prop="username" :rules="{required: true, validator: checkUsername, trigger: 'blur'}"><el-input v-model="loginData.username" placeholder="请输入帐号/手机号" maxlength="30" prefix-icon="ele-User" clearable/></el-form-item><el-form-item prop="password" :rules="{required: true, validator: checkPassword, trigger: 'blur'}"><el-input v-model="loginData.password" type="password" placeholder="请输入密码" maxlength="30" prefix-icon="ele-Unlock" show-password clearable/></el-form-item><el-form-item><div class="login-other"><el-checkbox v-model="isRemember"><span>记住密码</span></el-checkbox></div><el-button class="login-submit" @click="submitForm()"  :loading="loading"  type="primary"> 登 录 </el-button></el-form-item></el-form></div></div>
    </template><style lang="scss" scoped>
    .login-container {height: 100%;width: 100%;background-image: url('@/assets/loginBj.png');background-size: cover;overflow: hidden;display: flex;align-items: center;// justify-content: center;.login-wrap {width: 410px;height: 460px;background-color: #fff;padding: 30px;margin: auto;margin-right: 130px;box-shadow: #74747462 0 2px 15px;border-radius: 10px;.lagin-logo {max-width: 130px;margin: auto;display: flex;}.login-title {font-size: 20px;height: 70px;line-height: 70px;font-weight: 500;text-align: left;color: #0d1234;letter-spacing: 2px;}.login-form {.el-form-item {margin-bottom: 27px;}.login-other {span {font-size: 13px;font-weight: 500;color: #999;}}.login-submit {width: 100%;height: 40px;letter-spacing: 3px;font-weight: 500;}}}}
    </style>
    

效果:
vue3的登录认证与退出登录

第三步、Pinia 管理认证状态

  1. 创建utils/storage.ts

    /*** window.localStorage 浏览器永久缓存* @method set 设置永久缓存* @method get 获取永久缓存* @method remove 移除永久缓存* @method clear 移除全部永久缓存*/
    export const Local = {// 设置永久缓存set(key: string, val: any) {window.localStorage.setItem(key, JSON.stringify(val || ''));},// 获取永久缓存get(key: string) {let json: any = window.localStorage.getItem(key);return JSON.parse(json);},// 移除永久缓存remove(key: string) {window.localStorage.removeItem(key);},// 移除全部永久缓存clear() {window.localStorage.clear();},
    };/*** window.sessionStorage 浏览器临时缓存* @method set 设置临时缓存* @method get 获取临时缓存* @method remove 移除临时缓存* @method clear 移除全部临时缓存*/
    export const Session = {// 设置临时缓存set(key: string, val: any) {// val为undefined保存时,当get时parse转成json对象会失败,加上 || ''解决这个window.sessionStorage.setItem(key, JSON.stringify(val || ''));},// 获取临时缓存get(key: string) {let json: any = window.sessionStorage.getItem(key);// parse 无法对undefined 和 ''进行解析的return JSON.parse(json);},// 移除临时缓存remove(key: string) {window.sessionStorage.removeItem(key);},// 移除全部临时缓存clear() {window.sessionStorage.clear();},
    };
  2. src/types/pinia.d.ts 定义 认证状态 类型:

    // 用户认证信息
    declare interface AuthState<T = any> {rememberData?: LoginData; // 记住我(登录数据)accessToken?: string; //访问令牌
    }
    
  3. 创建 src/stores/auth.tsPinia 实现记住密码、登录处理:

记住密码:将登录信息保存下来。 提交登录信息处理,后端接口校验用户名密码正确后,会返回令牌 access_token ,将令牌保存;

import { defineStore } from 'pinia';
import type { RouteRecordRaw } from 'vue-router';
import { Session, Local } from '@/utils/storage';
import { login } from '@/api/auth';
// 保存到 Local或 Session的key名
export const Key = {rememberKey: 'isRemember', // 记住密码的keyaccessTokenKey: 'accessToken', // 访问令牌本地保存的key
}
/**
* 用户所拥有的路由权限
*/
export const useAuthStore = defineStore('auth', {state: (): AuthState<RouteRecordRaw> => {return {rememberData: Local.get(Key.rememberKey), // 记住密码accessToken: Session.get(Key.accessTokenKey), // 访问令牌字符串}},actions: {// 记住密码setRememberPwd(data?: LoginData) {this.rememberData = data;if (data) {Local.set(Key.rememberKey, { username: data.username, password: data.password });} else {Local.remove(Key.rememberKey);}},// 登录操作userLogin(loginData: LoginData) {return new Promise((resolve, reject) => {login(loginData).then((res: any) => {const { data } = res;// 状态赋值const { access_token } = data;this.accessToken = access_token;// 保存到session中Session.set(Key.accessTokenKey, access_token);// 正常响应钩子resolve(res);}).catch((error: Error) => {reject(error); // 异常});});},}
});

第四步、提交登录表单

  1. 创建api/auth/index.ts文件
    import request from "@/utils/request";
    const baseUrl = "/auth";
    // 登录系统
    export function login(data: LoginData) {return request({url: `${baseUrl}/token`,method: 'POST',data});
    }
    
  2. 实现表单登录按钮逻辑
    import { useAuthStore } from "@/stores/auth";
    const authStore = useAuthStore();
    const state = reactive({loading: false,isRemember: true, // 是否记住密码loginData: {username: authStore.rememberData?.username,password: authStore.rememberData?.password,} as LoginData,
    });// 提交登录
    function submitForm() {// 如果在登录中,不允许重复登录if (state.loading) return;formRef.value?.validate(async (valid: boolean) => {if (!valid) return false;try {// 登录中state.loading = true;// 记住密码authStore.setRememberPwd(state.isRemember ? state.loginData : undefined);// 发送登录请求await authStore.userLogin(state.loginData);// 跳转来源地址router.replace({ path: <string>route.query?.redirect || "/" });} catch (error) {} finally {}});
    }
    
  3. 效果
    vue3的登录认证与退出登录
    vue3的登录认证与退出登录

第六步、axios在请求头上添加认证token

  1. src/utils/request.tsaxios 请求拦截器中针对发送的验合法性:Authorization: Bearer ${accessToken}
    import { useAuthStore } from '@/stores/auth';
    // 请求拦截器
    request.interceptors.request.use(config => {// 在此处可向请求头加上认证tokenconst authStore = useAuthStore();// 获取tokenconst accessToken = authStore.accessToken;if (accessToken) {// oauth2 请求头 Authorization: Bearer xxxxxconfig.headers.Authorization = `Bearer ${accessToken}`;}return config;
    }, error => {// 出现异常, catch可捕获到return Promise.reject(error);
    })
    
  2. 观察登录的时候调用接口,接口中的请求头是否有token
    vue3的登录认证与退出登录

退出登录实现步骤

第一步、调用接口api方法 logout

import request from "@/utils/request";
const baseUrl = "/auth";
// 退出系统
export function logout() {return request({url: `${baseUrl}/logout`,method: 'POST',});
}

第二步、pinia 中实现退出功能

import { defineStore } from 'pinia';
import type { RouteRecordRaw } from 'vue-router';
import { Session, Local } from '@/utils/storage';
import { login, logout } from '@/api/auth';
// 保存到 Local或 Session的key名
export const Key = {rememberKey: 'isRemember', // 记住密码的keyaccessTokenKey: 'accessToken', // 访问令牌本地保存的keyuserInfoKey: 'userInfo', // 用户信息本地保存的key
}
/**
* 用户所拥有的路由权限
*/
export const useAuthStore = defineStore('auth', {state: (): AuthState<RouteRecordRaw> => {return {rememberData: Local.get(Key.rememberKey), // 记住密码accessToken: Session.get(Key.accessTokenKey), // 访问令牌字符串userInfo: Session.get(Key.userInfoKey),}},actions: {// 记住密码setRememberPwd(data?: LoginData) {this.rememberData = data;if (data) {Local.set(Key.rememberKey, { username: data.username, password: data.password });} else {Local.remove(Key.rememberKey);}},userLogout() {return new Promise((resolve, reject) => {logout().then((res: any) => {// 重置状态this.resetUserState();// 重新加载当前页,需认证页面会去登录页window.location.reload();resolve(res);}).catch((error: Error) => {reject(error);})});},// 重置用户状态resetUserState() {this.accessToken = undefined;this.userInfo = undefined;// 移除保存的数据Session.remove(Key.accessTokenKey);Session.remove(Key.userInfoKey);}}
});

第三步、触发退出登录事件

  1. src/layout/layoutHeader/userDropdown.vue 显示用户信息和点击退出系统 authStore.userLogout()
    <template><el-dropdown><template #dropdown><el-dropdown-menu><el-dropdown-item @click="authStore.userLogout()" divided>退出登录</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div>
    </template>
    <script lang="ts" setup>
    import { useFullscreen, useDark } from "@vueuse/core";
    import { useLayoutConfigStore } from "../../stores/layoutConfig";
    import { useRouter } from "vue-router";
    import { useAuthStore } from "../../stores/auth";
    const router = useRouter();
    const authStore = useAuthStore();
    const layoutConfig = useLayoutConfigStore();
    </script>
    

效果:
Vue3登录认证与退出登录

http://www.dtcms.com/wzjs/271459.html

相关文章:

  • 潜山云建站网站建设网站建设策划书案例
  • 公司网站开发计划书百度 营销推广靠谱吗
  • 建设个网站需要什么快速的网站设计制作
  • 新手学做网站相关书籍百度网盘云资源搜索引擎
  • 区住房城乡建设委(房管局)官方网站页面关键词优化
  • 如何加强网站内容建设seo工具优化软件
  • 网络教室网站建设大连seo优化
  • 恒星科技网站建设有没有专门做营销的公司
  • 怎么看一个网站用什么程序做的开鲁网站seo转接
  • 山东查询网站备案怎样在百度做广告宣传
  • 网站做担保交易站内优化主要从哪些方面进行
  • 中央政府门口网站建设理念万网域名
  • aspnet动态网站开发题目企业网站设计服务
  • 专业开发网站建设地推团队去哪里找
  • wordpress官方中文主题下载长春seo代理
  • 南宁网站seo大概多少钱外贸出口平台网站
  • 庐江网站广告怎么做上海专业网络推广公司
  • 学做馒头面包哪个网站好查看关键词被搜索排名的软件
  • 连接国外网站的app怎么创建自己的网站平台
  • 政府信息网站建设移动端关键词排名优化
  • 天津做网站哪家比较好品牌营销策划方案怎么做
  • 禁止浏览器访问一个网站怎么做搜索引擎优化的简写是
  • 百度收录网站怎么更改关键词网站开发北京公司
  • 阿里巴巴上做英文网站一年多少钱谷歌怎么推广自己的网站
  • 永久免费手机网站自助建站郑州seo询搜点网络效果佳
  • 做淘宝优惠卷网站步骤免费网站注册平台
  • 提供网站建设公司电话免费软文发布平台
  • 深圳网站建设公司的外文名是手机系统优化软件
  • 做国际网站的上海高端网站公司怎么在百度上免费做广告
  • 直接做那个视频网站贵阳网站建设制作