安装pinia,实现登录逻辑

main
lee-zt 2 weeks ago
parent 7f2c6fd73e
commit 5764b011e6

@ -11,6 +11,7 @@
"axios": "^1.8.4",
"core-js": "^3.8.3",
"element-plus": "^2.9.8",
"pinia": "^3.0.2",
"vue": "^3.2.13",
"vue-router": "^4.5.0"
},
@ -3136,6 +3137,30 @@
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT"
},
"node_modules/@vue/devtools-kit": {
"version": "7.7.6",
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.6.tgz",
"integrity": "sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==",
"license": "MIT",
"dependencies": {
"@vue/devtools-shared": "^7.7.6",
"birpc": "^2.3.0",
"hookable": "^5.5.3",
"mitt": "^3.0.1",
"perfect-debounce": "^1.0.0",
"speakingurl": "^14.0.1",
"superjson": "^2.2.2"
}
},
"node_modules/@vue/devtools-shared": {
"version": "7.7.6",
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.6.tgz",
"integrity": "sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==",
"license": "MIT",
"dependencies": {
"rfdc": "^1.4.1"
}
},
"node_modules/@vue/reactivity": {
"version": "3.5.13",
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz",
@ -3993,6 +4018,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/birpc": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.3.0.tgz",
"integrity": "sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz",
@ -4684,6 +4718,21 @@
"dev": true,
"license": "MIT"
},
"node_modules/copy-anything": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
"integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
"license": "MIT",
"dependencies": {
"is-what": "^4.1.8"
},
"engines": {
"node": ">=12.13"
},
"funding": {
"url": "https://github.com/sponsors/mesqueeb"
}
},
"node_modules/copy-webpack-plugin": {
"version": "9.1.0",
"resolved": "https://registry.npmmirror.com/copy-webpack-plugin/-/copy-webpack-plugin-9.1.0.tgz",
@ -6921,6 +6970,12 @@
"node": "*"
}
},
"node_modules/hookable": {
"version": "5.5.3",
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
"license": "MIT"
},
"node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@ -7464,6 +7519,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-what": {
"version": "4.1.16",
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
"integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
"license": "MIT",
"engines": {
"node": ">=12.13"
},
"funding": {
"url": "https://github.com/sponsors/mesqueeb"
}
},
"node_modules/is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz",
@ -8340,6 +8407,12 @@
"dev": true,
"license": "ISC"
},
"node_modules/mitt": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
"license": "MIT"
},
"node_modules/module-alias": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.3.tgz",
@ -8959,6 +9032,12 @@
"node": ">=8"
}
},
"node_modules/perfect-debounce": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
"integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
"license": "MIT"
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
@ -8978,6 +9057,36 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pinia": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.2.tgz",
"integrity": "sha512-sH2JK3wNY809JOeiiURUR0wehJ9/gd9qFN2Y828jCbxEzKEmEt0pzCXwqiSTfuRsK9vQsOflSdnbdBOGrhtn+g==",
"license": "MIT",
"dependencies": {
"@vue/devtools-api": "^7.7.2"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"typescript": ">=4.4.4",
"vue": "^2.7.0 || ^3.5.11"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/pinia/node_modules/@vue/devtools-api": {
"version": "7.7.6",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.6.tgz",
"integrity": "sha512-b2Xx0KvXZObePpXPYHvBRRJLDQn5nhKjXh7vUhMEtWxz1AYNFOVIsh5+HLP8xDGL7sy+Q7hXeUxPHB/KgbtsPw==",
"license": "MIT",
"dependencies": {
"@vue/devtools-kit": "^7.7.6"
}
},
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz",
@ -10297,6 +10406,12 @@
"node": ">=0.10.0"
}
},
"node_modules/rfdc": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
"license": "MIT"
},
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
@ -10890,6 +11005,15 @@
"wbuf": "^1.7.3"
}
},
"node_modules/speakingurl": {
"version": "14.0.1",
"resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
"integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -11033,6 +11157,18 @@
"postcss": "^8.2.15"
}
},
"node_modules/superjson": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
"integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
"license": "MIT",
"dependencies": {
"copy-anything": "^3.0.2"
},
"engines": {
"node": ">=16"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",

@ -11,6 +11,7 @@
"axios": "^1.8.4",
"core-js": "^3.8.3",
"element-plus": "^2.9.8",
"pinia": "^3.0.2",
"vue": "^3.2.13",
"vue-router": "^4.5.0"
},
@ -36,7 +37,9 @@
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
"rules": {
"vue/multi-word-component-names": "off"
}
},
"browserslist": [
"> 1%",

@ -4,7 +4,7 @@
<div class="logo-section">
<router-link to="/" class="logo-link">
<!-- Logo 图片 -->
<img src="@/assets/logo.png" alt="Logo" class="logo-img"/>
<img src="@/assets/logo.png" alt="Logo" class="logo-img" />
<!-- 标题区域包含中文和英文标题 -->
<div class="title-section">
<div class="divider-section">
@ -37,7 +37,14 @@
<!-- 登录/注册按钮 -->
<div class="nav-section">
<button @click="showModal" class="login-btn">登录/注册</button>
<button v-if="!isLoggedIn" @click="showModal" class="login-btn">/</button>
<div v-else class="user-avatar">
<img :src="userInfo.avatar || defaultAvatar" alt="用户头像" class="avatar-img" />
<div class="dropdown-menu">
<button @click="goToProfile"></button>
<button @click="logout">退</button>
</div>
</div>
</div>
<!-- 登录/注册模态框组件仅在 isModalVisible true 时显示 -->
@ -45,45 +52,59 @@
</header>
</template>
<script>
<script setup name="Header">
import { ref, computed } from 'vue';
import { useUserStore } from '@/stores/user.ts';
import LoginRegisterModal from './LoginRegisterModal.vue';
export default {
name: 'AppHeader',
components: {
LoginRegisterModal,
},
data() {
return {
isModalVisible: false,
colleges: [
{ name: '武大官网', url: 'https://www.whu.edu.cn/' },
{ name: '计算机学院', url: 'https://cs.whu.edu.cn/' },
{ name: '经济与管理学院', url: 'https://ems.whu.edu.cn/' },
{ name: '法学院', url: 'https://law.whu.edu.cn/' },
{ name: '物理科学与技术学院', url: 'https://physics.whu.edu.cn/' },
{ name: '化学与分子科学学院', url: 'https://chem.whu.edu.cn/' },
{ name: '生命科学学院', url: 'https://life.whu.edu.cn/' },
{ name: '外国语言文学学院', url: 'https://fls.whu.edu.cn/' },
{ name: '历史学院', url: 'https://history.whu.edu.cn/' },
{ name: '新闻与传播学院', url: 'https://jmc.whu.edu.cn/' },
{ name: '艺术与设计学院', url: 'https://artdesign.whu.edu.cn/' },
{ name: '体育学院', url: 'https://pe.whu.edu.cn/' },
{ name: '马克思主义学院', url: 'https://marx.whu.edu.cn/' },
{ name: '继续教育学院', url: 'https://jjy.whu.edu.cn/' },
{ name: '国际教育学院', url: 'https://gjjy.whu.edu.cn/' },
{ name: '网络与信息中心', url: 'https://nic.whu.edu.cn/' },
],
};
},
methods: {
showModal() {
this.isModalVisible = true;
},
hideModal() {
this.isModalVisible = false;
},
},
//
const userStore = useUserStore();
//
const isModalVisible = ref(false);
const colleges = ref([
{ name: '武大官网', url: 'https://www.whu.edu.cn/' },
{ name: '计算机学院', url: 'https://cs.whu.edu.cn/' },
{ name: '经济与管理学院', url: 'https://ems.whu.edu.cn/' },
{ name: '法学院', url: 'https://law.whu.edu.cn/' },
{ name: '物理科学与技术学院', url: 'https://physics.whu.edu.cn/' },
{ name: '化学与分子科学学院', url: 'https://chem.whu.edu.cn/' },
{ name: '生命科学学院', url: 'https://life.whu.edu.cn/' },
{ name: '外国语言文学学院', url: 'https://fls.whu.edu.cn/' },
{ name: '历史学院', url: 'https://history.whu.edu.cn/' },
{ name: '新闻与传播学院', url: 'https://jmc.whu.edu.cn/' },
{ name: '艺术与设计学院', url: 'https://artdesign.whu.edu.cn/' },
{ name: '体育学院', url: 'https://pe.whu.edu.cn/' },
{ name: '马克思主义学院', url: 'https://marx.whu.edu.cn/' },
{ name: '继续教育学院', url: 'https://jjy.whu.edu.cn/' },
{ name: '国际教育学院', url: 'https://gjjy.whu.edu.cn/' },
{ name: '网络与信息中心', url: 'https://nic.whu.edu.cn/' },
]);
//
const defaultAvatar = '@/assets/default-avatar.png';
//
const isLoggedIn = computed(() => userStore.isLoggedIn);
const userInfo = computed(() => userStore.userInfo);
//
const showModal = () => {
isModalVisible.value = true;
};
const hideModal = () => {
isModalVisible.value = false;
};
const goToProfile = () => {
//
//window.location.href = '/profile';
};
const logout = () => {
userStore.logout();
window.location.href = '/';
};
</script>

@ -75,6 +75,7 @@ import { ref, computed } from 'vue';
import axios from 'axios';
import request from '@/utils/request';
import { ElMessage } from 'element-plus';
import { useUserStore } from '@/stores/user.ts';
export default {
name: 'UserLogin',
@ -82,7 +83,7 @@ export default {
setup() {
const currentType = ref('username'); //
const cooldown = ref(0); //
const userStore = useUserStore(); //
//
const loginTypes = [
{ label: '用户名登录', value: 'username' },
@ -175,6 +176,14 @@ export default {
}
//
/*
function login1() {
userStore.login({
avatar: '/assets/default-avatar/boy_1.png',
userName: '珈人一号'
})
}*/
async function login() {
if (!isvalidForm.value) return;
@ -193,16 +202,23 @@ export default {
if (response.code === 200) {
//token
//
const { accessToken, refreshToken } = response.data;
localStorage.setItem('accessToken', accessToken);
localStorage.setItem('refreshToken', refreshToken);
userStore.login({
avatar: '/assets/default-avatar/boy_1.png',
userName: '珈人一号'
})
ElMessage({
message: '登录成功',
type: 'success',
duration: 500
});
//TODO:
//or
}else{
//
ElMessage({
@ -236,6 +252,7 @@ export default {
showVerifyCode,
cooldown,
sendCode,
//login1,
login,
switchLoginType,
isValidInput

@ -1,11 +1,13 @@
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // 确保引入了 router
import { createPinia } from 'pinia';
import ELementPlus from 'element-plus';
import 'element-plus/dist/index.css';
const app = createApp(App);
const pinia = createPinia(); // 创建 Pinia 实例
app.use(pinia); // 注册 Pinia
app.use(router); // 注册 vue-router
app.use(ELementPlus); // 注册 element-plus
app.mount('#app');

@ -0,0 +1,21 @@
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
isLoggedIn: false, // 登录状态
userInfo: {
avatar: '', // 用户头像 URL
username: '', // 用户名
},
}),
actions: {
login(userData) {
this.isLoggedIn = true;
this.userInfo = userData;
},
logout() {
this.isLoggedIn = false;
this.userInfo = { avatar: '', username: '' };
},
},
});
Loading…
Cancel
Save