Login + getInfo + Register 后端 API 书写, login + logout 前端书写

This commit is contained in:
2023-02-20 22:15:52 +08:00
parent 78db9a28c8
commit 0badc0f83d
23 changed files with 802 additions and 8 deletions
+47
View File
@@ -10,9 +10,56 @@ import NavBar from "./components/NavBar.vue";
// 导入 BootStrap 的 css 和 js 依赖以同步 BootStrap 样式
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap/dist/js/bootstrap";
// import $ from "jquery";
export default {
components: { NavBar },
/* setup: () => {
$.ajax({
url: "http://localhost:3000/user/account/token/",
type: "POST",
data: {
username: "bb",
password: "pbb",
},
success(resp) {
console.log(resp.token, "\n成功了\n", resp.error_message);
},
error(resp) {
console.log(resp);
},
});
$.ajax({
url: "http://localhost:3000/user/account/info/",
type: "GET",
headers: {
Authorization:
"Bearer " +
"eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIzODA2Yzc0ODkwYTE0NTgwYjcyOGQzOWI4NDYyYWY2ZSIsInN1YiI6IjYiLCJpc3MiOiJzZyIsImlhdCI6MTY3Njg4ODk5MywiZXhwIjoxNjc4MDk4NTkzfQ.mq7Xdt3G7VGvX7fgIYGN2MfH8bo9MuZ7V0nfzGmbDZ8",
},
success(resp) {
console.log(resp);
},
error(resp) {
console.log(resp);
},
});
$.ajax({
url: "http://localhost:3000/user/account/register/",
type: "POST",
data: {
username: "cc",
password: "pcc",
confirmedPassword: "pcc",
},
success(resp) {
console.log(resp);
},
error(resp) {
console.log(resp);
},
});
}, */
};
</script>
<style>
+39 -3
View File
@@ -27,7 +27,8 @@
>
</li>
</ul>
<ul class="navbar-nav">
<!-- 判断是否登录成功:如果登录成功,则修改导航栏这部分内容 -->
<ul class="navbar-nav" v-if="$store.state.user.is_login">
<!-- 下拉菜单样式 -->
<li class="nav-item dropdown">
<a
@@ -37,7 +38,7 @@
data-bs-toggle="dropdown"
aria-expanded="false"
>
flykhan
{{ $store.state.user.username }}
</a>
<ul class="dropdown-menu">
<li>
@@ -47,10 +48,36 @@
</li>
<!-- 下拉菜单分割线 -->
<li><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item" href="#">退出</a></li>
<!-- v-on:click 也可以写为 @click ; 给退出按钮加上手形状按钮样式 style="cursor: pointer"-->
<li>
<a class="dropdown-item" style="cursor: pointer" @click="logout">退出</a>
</li>
</ul>
</li>
</ul>
<ul class="navbar-nav" v-else>
<!-- 下拉菜单样式 -->
<li class="nav-item">
<router-link
class="nav-link"
:to="{ name: 'user_account_login' }"
role="button"
>
登录
</router-link>
</li>
<li class="nav-item">
<router-link
class="nav-link"
:to="{ name: 'user_account_register' }"
role="button"
>
注册
</router-link>
</li>
</ul>
</div>
</div>
</nav>
@@ -59,15 +86,24 @@
<script>
import { useRoute } from "vue-router";
import { computed } from "vue";
import { useStore } from "vuex";
export default {
setup() {
const store = useStore();
const route = useRoute();
// 用于判断当前选中的是哪个 nav-link 链接,结合上文操作将选中的 nav-link 改为 nav-link active 模式
let route_name = computed(() => route.name);
const logout = () => {
console.log("退出前:" + store.state.user.token);
store.dispatch("logout");
console.log("退出后:" + store.state.user.token);
};
return {
route_name,
logout,
};
},
};
+12
View File
@@ -5,6 +5,8 @@ import RanklistIndexView from '../views/ranklist/RanklistIndexView.vue'
import RecordIndexView from '../views/record/RecordIndexView.vue'
import UserBotIndexView from '../views/user/bot/UserBotIndexView.vue'
import NotFound from '../views/error/NotFound.vue'
import UserAccountLoginView from '@/views/user/account/UserAccountLoginView.vue'
import UserAccountRegisterView from '@/views/user/account/UserAccountRegisterView.vue'
// 定义所有页面的 URL 路由
@@ -35,6 +37,16 @@ const routes = [
name:'user_bot_index',
component:UserBotIndexView
},
{
path:'/user/account/login/',
name:'user_account_login',
component:UserAccountLoginView
},
{
path:'/user/account/register/',
name:'user_account_register',
component:UserAccountRegisterView
},
{
path:'/404/',
name:'404',
+3
View File
@@ -1,4 +1,5 @@
import { createStore } from 'vuex'
import ModuleUser from './user'
export default createStore({
state: {
@@ -10,5 +11,7 @@ export default createStore({
actions: {
},
modules: {
user: ModuleUser,
}
})
+100
View File
@@ -0,0 +1,100 @@
import $ from 'jquery'
export default {
state: {
id: "",
username: "",
photo: "",
token: "",
is_login: false,
},
getters: {
},
// 同步事件
mutations: {
// 更新用户信息
updateUser(state, user){
state.id = user.id;
state.username = user.username;
state.photo = user.photo;
state.is_login = user.is_login;
},
// 更新用户 Token
updateToken(state, token){
state.token = token;
},
// 退出登录
logout(state){
state.id = "";
state.username = "";
state.photo = "";
state.token = "";
state.is_login = false;
}
},
// 异步事件
actions: {
// 登录函数
login(context, data){
$.ajax({
url: "http://localhost:3000/user/account/token/",
type: "POST",
data: {
username: data.username,
password: data.password,
},
success(resp) {
// console.log(resp.token, "\n成功了\n", resp.error_message);
if(resp.error_message === "success"){
/*
登录成功则将获取到的 resp 里的 token 传给 mutations 里的
updateToken 方法,对用户 token 信息进行更新
*/
context.commit("updateToken", resp.token);
data.success(resp);
} else {
data.error(resp);
}
},
error(resp) {
data.error(resp);
},
});
},
// 获取登录成功后的用户信息
getinfo(context,data){
$.ajax({
url: "http://localhost:3000/user/account/info/",
type: "GET",
headers: {
Authorization:
"Bearer " + context.state.token,
},
success(resp) {
if(resp.error_message === "success"){
// 更新用户信息
context.commit("updateUser",{
...resp, // 解构 resp 中的内容
is_login: true, // 登录成功,将 is_login 置为 true
});
data.success(resp); // 调用回调函数
} else {
data.error(resp);
}
},
error(resp) {
data.error(resp);
},
});
},
logout(context){
context.commit("logout");
}
},
modules: {
}
}
@@ -0,0 +1,98 @@
<template>
<ContentBase>
<!-- justify-content-md-center 用于居中 -->
<div class="row justify-content-md-center">
<div class="col-3">
<!-- 定义登录表单 @submita="login" 表示表单提交时触发 login 函数; submit.prevent 用于阻止 submit 的默认提交行为,
而是调用自己定义的 login 函数来实现提交行为
-->
<form @submit.prevent="login">
<div class="mb-3">
<label for="username" class="form-label">用户名</label>
<!-- 使用 v-model 来绑定函数里的 username 变量 -->
<input
v-model="username"
type="text"
class="form-control"
id="username"
placeholder="请输入用户名"
/>
</div>
<div class="mb-3">
<label for="password" class="form-label">密码</label>
<input
v-model="password"
type="password"
class="form-control"
id="password"
placeholder="请输入密码"
/>
</div>
<div class="error-message">{{ error_message }}</div>
<!-- float-start 左布局, float-end 右布局 -->
<!-- type="submit" 提交类型 -->
<button type="submit" class="btn btn-primary btn-sm float-center">登录</button>
</form>
</div>
</div>
</ContentBase>
</template>
<script>
import ContentBase from "../../../components/ContentBase.vue";
import { useStore } from "vuex";
import { ref } from "vue";
import router from "../../../router/index";
export default {
components: {
ContentBase,
},
setup: () => {
const store = useStore();
let username = ref("");
let password = ref("");
let error_message = ref("");
const login = () => {
error_message.value = "";
// 如果触发,则调用 store/user.js 里定义的 login 函数
store.dispatch("login", {
username: username.value,
password: password.value,
success() {
// 登录成功,首先更新用户信息
store.dispatch("getinfo", {
success() {
// 登录成功,则跳转到首页
router.push({ name: "home" });
console.log(store.state.user);
},
});
},
error() {
// console.log(resp);
error_message.value = "用户名或密码错误";
},
});
};
return {
username,
password,
error_message,
login,
};
},
};
</script>
<style scoped>
div.error-message {
color: red;
}
button {
width: 100%;
}
</style>
@@ -0,0 +1,15 @@
<template>
<ContentBase>注册</ContentBase>
</template>
<script>
import ContentBase from "../../../components/ContentBase.vue";
export default {
components: {
ContentBase,
},
};
</script>
<style scoped></style>