Login + getInfo + Register 后端 API 书写, login + logout 前端书写
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user