开始一个vue项目-day2

这次新增的功能有:

1、使用cookie存储token

参考网站:https://vueuse.org/

安装包:

npm i @vueuse/integrations

npm i universal-cookie@^7

2、cookie的设置读取和删除,代码:composables/auth.js

import { useCookies } from '@vueuse/integrations/useCookies'const cookie = useCookies()
const tokenKey = "admin-token"export function setToken(token){return cookie.set(tokenKey, token)
}
// 读取tokenexport function getToken(){return cookie.get(tokenKey)
}// 删除token
export function deleteToken(){return cookie.remove(tokenKey)
}

3、存储token

统一封装到permission.js

4、添加拦截器,axios中文文档|axios中文网 | axios,代码axios.js

import { createStore } from 'vuex'
import { setToken } from '~/composables/auth';
import { getInfo } from '~/api/manager'
import { login } from '~/api/manager'
import { deleteToken } from '../composables/auth';
// // 创建一个新的 store 实例
const store = createStore({state() {return {// 用户信息user: {}}},mutations: {// 记录用户信息SET_USERINFO(state, user) {state.user = user}},actions: {// 登录login({ commit }, { username, password }) {return new Promise((resolve, reject) => {login(username, password).then(res => {setToken(res.token)resolve(res)}).catch(err => reject(err))})},// 获取当前登录用户信息getInfo({ commit }) {return new Promise((resolve, reject) => {getInfo().then(res => {commit("SET_USERINFO", res)resolve(res)}).catch(err => reject(err))})},// 退出登录logout({ commit }) {// 移除cookie里面的tokendeleteToken()// 清楚当前用户状态vuexcommit("SET_USERINFO", {})}},})export default store

5、抽出统一的方法,在manager.js里:

import axios from "~/axios"export function login(username, password){
return axios.post("/admin/login",{username,password
})
}export function getInfo(){return axios.post("/admin/getinfo")}export function logout(){return axios.post("/admin/logout")}

6、写一个Util,封装成功或失败的提示方法

import { ElNotification } from 'element-plus'
import { fa } from 'element-plus/es/locales.mjs'
import { ElMessage, ElMessageBox } from 'element-plus'// 成功提示
export function toast(message, type = "success", dangerouslyUseHTMLString=false){ElNotification({message,type,dangerouslyUseHTMLString,duration: 3000})
}export function showModel(content = "提示内容", type = "warning",title=""){return ElMessageBox.confirm(content,title,{confirmButtonText: '确认',cancelButtonText: '取消',type: type,})
}

7、Vuex的状态管理,参考网站:https://vuex.vuejs.org/zh/

可以将我们登录完之后拿到的用户信息共享给其它页面和组件

安装:npm install vuex@next --save

a、新建:store/index.js

import { createStore } from 'vuex'
import { setToken } from '~/composables/auth';
import { getInfo } from '~/api/manager'
import { login } from '~/api/manager'
import { deleteToken } from '../composables/auth';
// // 创建一个新的 store 实例
const store = createStore({state() {return {// 用户信息user: {}}},mutations: {// 记录用户信息SET_USERINFO(state, user) {state.user = user}},actions: {// 登录login({ commit }, { username, password }) {return new Promise((resolve, reject) => {login(username, password).then(res => {setToken(res.token)resolve(res)}).catch(err => reject(err))})},// 获取当前登录用户信息getInfo({ commit }) {return new Promise((resolve, reject) => {getInfo().then(res => {commit("SET_USERINFO", res)resolve(res)}).catch(err => reject(err))})},// 退出登录logout({ commit }) {// 移除cookie里面的tokendeleteToken()// 清楚当前用户状态vuexcommit("SET_USERINFO", {})}},})export default store

b、在main.js里面引入

import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import router from './router'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import store from './store'
import "./permission"const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)}
app.use(ElementPlus)
app.use(router)
app.use(store)
import 'virtual:windi.css'
app.mount('#app')

8、前置守卫,每次访问接口都通过这个判断有没有权限没权限就拒绝:

导航守卫 | Vue Router

a、permission.js

import router from "~/router"
import {getToken} from "~/composables/auth"
import {toast} from "~/components/util"
import store from "./store"// 前置守卫
router.beforeEach(async (to, from, next) => {console.log("前置守卫")const token = getToken()console.log(token)console.log(to.path)// 没有登录,强制跳转为登录页面if (!token && to.path != "/login"){toast("请先登录", "error")return next({path:"/login"})}// 防止重复登录console.log(to.path)if (token && to.path == "/login"){toast("不允许重复登录", "error")return next({path:from.path ? from.path : "/"})}// 如果用户登录了,自动获取用户信息存储到vuexif (token){// 异步操作,添加awaitxawait store.dispatch("getInfo")}next()})

b、需要在main.js里面引入

import "./permission"

9、添加键盘事件

a、输入密码即可回车登录,F12,查看打印的信息

b、具体代码见:login.vue

10、退出登录

以上所有功能完整的login.vue代码:

<template><el-row class="login-container"><el-col :lg="16" :md="12" class="left"><div><div class="font-bold text-5xl text-light-50 mb-4">欢迎光临</div><div class="text-gray-200 text-sm">此站点是学习演示</div></div></el-col><el-col :lg="8" :md="12" class="right"><h2 class="title">欢迎回来</h2><div class=""><span class="line"></span><span>账号密码登录</span><span class="line"></span></div><el-form ref="formRef" :model="form" class="w-[250px]" :rules="rules"><el-form-item prop="username"><el-input v-model="form.username" placeholder="请输入用户名"><template #prefix><el-icon><User /></el-icon></template></el-input></el-form-item><el-form-item prop="password"><el-input v-model="form.password" placeholder="请输入密码" type="password" show-password><template #prefix><el-icon><Lock /></el-icon></template></el-input></el-form-item><el-form-item><el-button class="w-[250px]" type="primary" round @click="onSubmit" color="#626aef" :loading="loadding">登录</el-button></el-form-item></el-form></el-col></el-row>
</template><script setup>
import { reactive, ref, onMounted, onBeforeUnmount } from 'vue';
// import { User, Lock} from '@element-plus/icons-vue'
import { login } from '~/api/manager'
import { toast } from '~/components/util';
// import { getInfo } from '~/api/manager'
import { ElNotification } from 'element-plus'import { useRouter } from 'vue-router';
import { Loading } from '@element-plus/icons-vue';
import { fa, tr } from 'element-plus/es/locales.mjs';
import { setToken } from '~/composables/auth';
import { useStore } from 'vuex';
const router = useRouter()
const store = useStore()
const loadding = ref(false)
const form = reactive({username: '',password: ''
})
const rules = {username: [{required: true,message: '请输入用户名',trigger: 'blur',},// {//     min: 6,//     max: 6,//     message: '用户名长度必须是6个字符',//     trigger: 'blur'// }],password: [{required: true,message: '请输入密码',trigger: 'blur',}]
}// 对表单输入的值做校验
const formRef = ref(null)const onSubmit = () => {formRef.value.validate((valid) => {console.log('valid')if (!valid) {return false}loadding.value = trueconsole.log("开始请求接口")store.dispatch("login", form).then(res=>{toast("登录成功")router.push("/")}).finally(()=>{loadding.value = false})// login(form.username, form.password).then(res => {//     console.log(res)//     toast("登录成功")// 提示成功// ElNotification({//     message: "登录成功",//     type: 'success',//     duration: 3000// })// 存储用户相关信息// const cookie = useCookies()// setToken(res.token)// cookie.set("admin-token", res.token)// 获取用户相关信息// getInfo().then(res2 =>{//     store.commit('SET_USERINFO', res2)//     console.log(res2)// })// 跳转后台首页//         router.push("/")//     }).finally(()=>{//     loadding.value = false// })})
}// 监听回车事件
function onKeyUp(e){console.log(e)if (e.key == "Enter") onSubmit()
}// 添加键盘监听
onMounted(()=>{document.addEventListener("keyup", onKeyUp)})// 移除键盘监听
onBeforeUnmount(()=>{document.removeEventListener("keyup", onKeyUp)
})
</script><style scoped>
.login-container {@apply min-h-screen bg-indigo-500
}.login-container .left, .login-container .right {@apply flex items-center justify-center
}.login-container .right {@apply bg-light-50 flex-col
}.login-container .right .title {@apply font-bold text-3xl text-gray-900
}.login-container .right>div {@apply flex items-center justify-center my-5 space-x-2 text-gray-300
}.login-container .right>div .line {@apply h-[1px] w-16 bg-gray-200
}
</style>

11、完整的包路径

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/79392.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「Mac畅玩AIGC与多模态18」开发篇14 - 多字段输出与结构控制工作流示例

一、概述 本篇在输入变量基础上,演示如何通过执行 LLM 节点输出多个结构化字段,并传递至结束节点。开发人员将掌握如何配置结构化输出格式,实现提示词与字段的准确映射,为后续引入条件判断、循环结构等逻辑控制建立结构输出规范基础。 二、环境准备 macOS 系统Dify 平台已…

JWT解析

什么是JWT JSON Web Token &#xff08;JWT&#xff09; 是一种开放标准 &#xff08;RFC 7519&#xff09;&#xff0c;它定义了一种紧凑且独立的方式&#xff0c;用于在各方之间以 JSON 对象的形式安全地传输信息。此信息可以验证和信任&#xff0c;因为它是经过数字签名的。…

C语言中的自定义类型 —— 结构体.位段.联合体和枚举

自定义类型 1. 前言2. 结构体2.1 结构体的声明2.2 结构体变量的定义和初始化2.3 结构体的特殊声明2.4 结构体的自引用2.5 结构体的内存对齐2.6 修改默认对齐数2.7 结构体传参 3. 位段4. 联合体5. 枚举6. 结言 1. 前言 在C语言中已经为用过户提供了内置类型&#xff0c;如&…

StarRocks 查询优化器深度解析

StarRocks 查询优化器概览 1. Development History of StarRocks 过去五年&#xff0c;StarRocks 发布了三个大版本&#xff1a; StarRocks 1.0&#xff1a;通过向量化引擎和 CBO&#xff0c;打造极速 OLAP 数据库。 StarRocks 2.0&#xff1a;通过主键模型、数据湖分析和查询…

如何提高情商?(优化版)

引言 提高情商&#xff08;EQ&#xff09;是一个需要长期练习和自我反思的过程&#xff0c;核心在于理解自己、管理情绪、共情他人并有效沟通。以下是一些具体且可操作的方法&#xff0c;结合理论和实际场景&#xff0c;帮助你逐步提升&#xff1a; 一、核心方法&#xff1a;…

Python爬虫实战:获取好大夫在线各专业全国医院排行榜数据并分析,为患者就医做参考

一、引言 在当今医疗资源丰富但分布不均的背景下,患者在选择合适的心血管内科医院时面临诸多困难。好大夫在线提供的医院排行榜数据包含了医院排名、线上服务得分、患者评价得分等重要信息,对患者选择医院具有重要的参考价值。本研究通过爬取该排行榜数据,并进行深入分析,…

【AI面试准备】电商购物车AI测试设计与实施

面试题&#xff1a;案例实践&#xff1a; 为电商购物车设计AI测试&#xff1a;通过用户行为日志训练点击路径预测模型&#xff0c;动态生成边界条件测试用例。 为了顺利通过面试&#xff0c;回答应结构清晰、技术深入&#xff0c;并突出实际应用与创新。以下为分步解答&#…

Java 中使用 Callable 创建线程的方法

一、Callable 接口概述​ Callable接口位于java.util.concurrent包中&#xff0c;与Runnable接口类似&#xff0c;同样用于定义线程执行的任务&#xff0c;但它具有以下独特特性&#xff1a;​ 支持返回值&#xff1a;Callable接口声明了一个call()方法&#xff0c;该方法会在…

2025-SMS短信验证服务或存风险,小心账号隐私“失守”

近期&#xff0c;火绒安全情报中心监测到一款伪装成具备SMS短信验证码接收服务的程序。该程序通过部署持久化后门&#xff08;即僵尸网络节点&#xff09;窃取敏感信息。火绒安全提醒广大用户务必从官方或可信渠道下载软件&#xff0c;避免因使用来路不明的程序而导致账号被盗或…

docker部署Open WebUI下载速度慢解决方法

docker pull ghcr.nju.edu.cn/open-webui/open-webui:main改成这个就可以了

气泡图、桑基图的绘制

1、气泡图 使用气泡图分析某一年中国同欧洲各国之间的贸易情况。 气泡图分析的三个维度&#xff1a; • 进口额&#xff1a;横轴 • 出口额&#xff1a;纵轴 • 进出口总额&#xff1a;气泡大小 数据来源&#xff1a;链接: 国家统计局数据 数据概览&#xff08;进出口总额&…

前端面经-VUE3篇(三)--vue Router(二)导航守卫、路由元信息、路由懒加载、动态路由

一、导航守卫 vue Router 中的 导航守卫&#xff08;Navigation Guards&#xff09; 是一个非常重要的功能&#xff0c;用于在路由切换过程中&#xff0c;拦截、控制、检查或延迟页面跳转。 你可以理解为&#xff1a; &#x1f510; “进门前的保安”&#xff0c;控制哪些页面…

MATLAB实现二氧化硅和硅光纤的单模光波特性与仿真

一.二氧化硅和硅光纤的单模光波特性 利用麦克斯方程的精确解研究二氧化硅和硅亚波长直径导线的单模光波特性。研究了单模条件、模场。 二氧化硅光纤导线是圆形截面&#xff0c;包层是空气包层&#xff0c;阶梯型变化的折射率&#xff0c;导线线径D非常小长度足够长&#xff0…

【Linux系统】第二节—基础指令(2)

hello ~ 好久不见 自己想要的快乐要自己好好争取&#xff01; 云边有个稻草人-个人主页 Linux—本篇文章所属专栏—欢迎订阅—持续更新中 目录 本节课核心指令知识点总结 本节基本指令详解 07.man 指令 08.cp 指令 09.mv 指令 10.cat 指令 11.more 指令 12.less 指令 …

为了结合后端而学习前端的学习日志——【黑洞光标特效】

前端设计专栏 今天给大家带来一个超酷的前端特效——黑洞光标&#xff01;让你的鼠标变成一个会吞噬光粒子的迷你黑洞&#xff0c;点击时还会喷射出绿色能量粒子&#xff01;&#x1f320; &#x1f680; 效果预览 想象一下&#xff1a;你的鼠标变成一个旋转的黑洞&#xff0…

[硬件电路-11]:模拟电路常见元器件 - 什么是阻抗、什么是输入阻抗、什么是输出阻抗?阻抗、输入阻抗与输出阻抗的全面解析

1. 阻抗&#xff08;Impedance&#xff09; 定义&#xff1a;阻抗是电路或元件对交流信号&#xff08;AC&#xff09;流动的阻碍能力&#xff0c;用符号Z表示&#xff0c;单位为欧姆&#xff08;Ω&#xff09;。它综合了电阻&#xff08;R&#xff09;、电感&#xff08;L&am…

机器学习和深度学习的对比

深度 数据经过深层网络后&#xff0c;语义信息表征能力强&#xff0c;对几何细节信息表征能力弱。 数据依赖性 深度学习算法需要大量的数据来训练&#xff0c;而传统的机器学习使用制定的规则。所以&#xff0c;当数据量少时&#xff0c;深度学习的性能差于机器学习&#xf…

Kubernetes 安装 minikube

安装 minikube 在 Ubuntu 上安装 minikube minikube 是一个工具&#xff0c;它可以在本地快速运行一个单节点的 Kubernetes 集群。它主要用于&#xff1a;本地学习 Kubernetes、测试和开发 Kubernetes 应用程序、快速尝试 Kubernetes 的功能。 系统配置最低要求如下 CPU&#…

【学习笔记】深度学习:典型应用

作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程&#xff0c;深度学习领域研究生必读教材),开始深度学习领域学习&#xff0c;深入全面的理解深度学习的理论知识。 之前的文章参考下面的链接&#xf…

ComputeShader绘制全屏纯色纹理

参考 Getting Started With Compute Shaders In Unity 环境 Win10 Unity20194.40 全屏纯色纹理示例 使用ComputerShader逐个像素设置颜色 ComputeShader脚本 设置纹理颜色 #pragma kernel CSMainRWTexture2D<float4> Result;//纹理 half4 solidColor;//颜色[numth…