開始一個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.pswp.cn/pingmian/79392.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79392.shtml
英文地址,請注明出處:http://en.pswp.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…