Vue用户模块前端代码统一展示
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
原文地址:Vue用户模块前端代码统一展示 - Pleasure的博客
下面是正文内容:
前言
这里仅提供前端代码,前端具体实现的讲解和后端的内容可以参考我之前的专栏。
前端专栏:https://blog.csdn.net/2302_79791164/category_12617467.html
后端专栏:https://blog.csdn.net/2302_79791164/category_12611545.html
由于后端jar包打包的路径和方式因人而异这里就不提供文件了。
正文
默认类文件
App.vue
<script setup>
</script>
<template>
<router-view></router-view>
</template>
<style scoped>
</style>
main.js
import './assets/main.scss'
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import router from '@/router/index.js'
import App from './App.vue'
import { createPinia } from 'pinia'
import { createPersistedState } from 'pinia-persistedstate-plugin'
//添加全局路由守卫
router.beforeEach((to, from, next) => {
// 从 localStorage 中获取 token
const token = localStorage.getItem('token')
if (!token && to.path !== '/login') {
next('/login')
} else {
next()
}
})
const app = createApp(App);
const pinia = createPinia();
const persist = createPersistedState();
pinia.use(persist);
app.use(pinia);
app.use(router);
app.use(ElementPlus);
app.mount('#app')
展示类页面(views文件夹)
Login.vue(图片自行选择,命名为login_bg.jpg,放置到assets文件夹下)
<script setup>
import { User, Lock } from '@element-plus/icons-vue'
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
//控制注册与登录表单的显示, 默认显示注册
const isRegister = ref(false)
//定义注册模型
const registerData = ref({
username: '',
password: '',
rePassword: ''
})
//校验密码的函数
const checkRePassword = (rule, value, callback) => {
if (value === "") {
callback(new Error('请再次输入密码'))
} else if (value !== registerData.value.password) {
callback(new Error('两次输入密码不一致'))
} else {
callback()
}
}
//定义表单校验规则
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, max: 16, message: '长度为 5 到 16 个字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 5, max: 16, message: '长度为 5 到 16 个字符', trigger: 'blur' }
],
rePassword: [
{ validator: checkRePassword, trigger: 'blur' },
]
}
//调用后台接口完成注册
import { userRegisterService, userLoginService } from '@/api/user.js'
const register = async () => {
//register是一个相应式对象
let result = await userRegisterService(registerData.value);
/*if (result.code === 0) {
alert(result.msg ? result.msg : '注册成功');
} else {
alert(result.msg ? result.msg : '注册失败');
}*/
//alert(result.msg ? result.msg : '注册成功');
ElMessage.success(result.msg ? result.msg : '注册成功');
}
//绑定数据,复用注册表单的数据模型
//表单数据校验
//登录函数
import { useTokenStore } from '@/stores/token.js'
import { useRouter } from 'vue-router'
const router = useRouter()
const tokenStore = useTokenStore()
const login = async () => {
//调用接口完成登录
let result = await userLoginService(registerData.value);
/*if (result.code === 0) {
alert(result.msg ? result.msg : '登录成功');
} else {
alert(result.msg ? result.msg : '登录失败');
}*/
//alert(result.msg ? result.msg : '登录成功');
ElMessage.success(result.msg ? result.msg : '登录成功');
//把得到的token储存到pinia中
tokenStore.setToken(result.data)
localStorage.setItem('token',result.data)
//跳转到首页,借助路由完成跳转
router.push('/')
}
//定义函数,清空数据模型的数据
const clearRegisterData = () => {
registerData.value.username = '';
registerData.value.password = '';
registerData.value.rePassword = '';
}
</script>
<template>
<el-row class="login-page">
<el-col :span="12" class="bg"></el-col>
<el-col :span="6" :offset="3" class="form">
<!-- 注册表单 -->
<el-form ref="form" size="large" autocomplete="off" v-if="isRegister" :model="registerData" :rules="rules">
<el-form-item>
<h1>注册</h1>
</el-form-item>
<el-form-item prop="username">
<el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input :prefix-icon="Lock" type="password" placeholder="请输入密码"
v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item prop="rePassword">
<el-input :prefix-icon="Lock" type="password" placeholder="请输入再次密码"
v-model="registerData.rePassword"></el-input>
</el-form-item>
<!-- 注册按钮 -->
<el-form-item>
<el-button class="button" type="primary" auto-insert-space @click="register">
注册
</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" :underline="false" @click="isRegister = false;clearRegisterData()">
← 返回
</el-link>
</el-form-item>
</el-form>
<!-- 登录表单 -->
<el-form ref="form" size="large" autocomplete="off" v-else :model="registerData" :rules="rules">
<el-form-item>
<h1>登录</h1>
</el-form-item>
<el-form-item prop="username">
<el-input :prefix-icon="User" placeholder="请输入用户名" v-model="registerData.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input name="password" :prefix-icon="Lock" type="password" placeholder="请输入密码"
v-model="registerData.password"></el-input>
</el-form-item>
<el-form-item class="flex">
<div class="flex">
<el-checkbox>记住密码</el-checkbox>
<el-link type="primary" :underline="false">忘记密码?</el-link>
</div>
</el-form-item>
<!-- 登录按钮 -->
<el-form-item>
<el-button class="button" type="primary" auto-insert-space @click="login">登录</el-button>
</el-form-item>
<el-form-item class="flex">
<el-link type="info" :underline="false" @click="isRegister = true;clearRegisterData()">
注册 →
</el-link>
</el-form-item>
</el-form>
</el-col>
</el-row>
</template>
<style lang="scss" scoped>
.login-page {
height: 100vh;
background-color: #fff;
.bg {
background:
url('@/assets/login_bg.jpg') no-repeat center / cover;
border-radius: 0 20px 20px 0;
}
.form {
display: flex;
flex-direction: column;
justify-content: center;
user-select: none;
.title {
margin: 0 auto;
}
.button {
width: 100%;
}
.flex {
width: 100%;
display: flex;
justify-content: space-between;
}
}
}
</style>
Layout.vue
<script setup>
import {
Management,
Promotion,
UserFilled,
User,
Crop,
EditPen,
SwitchButton,
CaretBottom
} from '@element-plus/icons-vue'
import avatar from '@/assets/default.png'
</script>
<template>
<el-container class="layout-container">
<!-- 左侧菜单 -->
<el-aside width="200px">
<div class="el-aside__logo"></div>
<el-menu active-text-color="#ffd04b" background-color="#232323" text-color="#fff" router>
<el-menu-item index="/user/info">
<el-icon>
<Management />
</el-icon>
<span>文章分类</span>
</el-menu-item>
<el-menu-item>
<el-icon>
<Promotion />
</el-icon>
<span>文章管理</span>
</el-menu-item>
<el-sub-menu>
<template #title>
<el-icon>
<UserFilled />
</el-icon>
<span>个人中心</span>
</template>
<el-menu-item>
<el-icon>
<User />
</el-icon>
<span>基本资料</span>
</el-menu-item>
<el-menu-item>
<el-icon>
<Crop />
</el-icon>
<span>更换头像</span>
</el-menu-item>
<el-menu-item>
<el-icon>
<EditPen />
</el-icon>
<span>重置密码</span>
</el-menu-item>
</el-sub-menu>
</el-menu>
</el-aside>
<!-- 右侧主区域 -->
<el-container>
<!-- 头部区域 -->
<el-header>
<div>测试:<strong>Yiming</strong></div>
<el-dropdown placement="bottom-end">
<span class="el-dropdown__box">
<el-avatar :src="avatar" />
<el-icon>
<CaretBottom />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="profile" :icon="User">基本资料</el-dropdown-item>
<el-dropdown-item command="avatar" :icon="Crop">更换头像</el-dropdown-item>
<el-dropdown-item command="password" :icon="EditPen">重置密码</el-dropdown-item>
<el-dropdown-item command="logout" :icon="SwitchButton">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-header>
<!-- 中间区域 -->
<el-main>
<router-view></router-view>
</el-main>
<!-- 底部区域 -->
<el-footer></el-footer>
</el-container>
</el-container>
</template>
<style lang="scss" scoped>
.layout-container {
height: 100vh;
.el-aside {
background-color: #232323;
&__logo {
height: 120px;
background: url('') no-repeat center / 120px auto;
}
.el-menu {
border-right: none;
}
}
.el-header {
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
.el-dropdown__box {
display: flex;
align-items: center;
.el-icon {
color: #999;
margin-left: 10px;
}
&:active,
&:focus {
outline: none;
}
}
}
.el-footer {
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #666;
}
}
</style>
UserInfo.vue
<template>
用户信息
</template>
接口类文件(api文件夹)
user.js
//导入request.js请求工具
import request from '@/utils/request.js'
//提供调用注册接口的函数
export const userRegisterService = (registerData) => {
//借助于UrlSearchParams完成传递
const params = new URLSearchParams()
for (let key in registerData) {
params.append(key, registerData[key]);
}
return request.post('/user/register', params);
}
//提供调用登录接口的函数
export const userLoginService = (loginData) => {
//借助于UrlSearchParams完成传递
const params = new URLSearchParams()
for (let key in loginData) {
params.append(key, loginData[key]);
}
return request.post('/user/login', params);
}
路由类文件(router文件夹)
index.js
import { createRouter, createWebHistory } from 'vue-router'
//导入组件
import LoginVue from '@/views/Login.vue'
import LayoutVue from '@/views/Layout.vue'
import UserInfoVue from '@/views/user/UserInfo.vue'
//定义路由关系
const routes = [
{ path: '/login', component: LoginVue },
{
path: '/', component: LayoutVue, children: [
{ path: '/user/info', component: UserInfoVue }
]
}
]
//创建路由器
const router = createRouter({
history: createWebHistory(),
routes: routes
})
//导出路由
export default router
状态类文件(stores文件夹)
token.js
import { defineStore } from "pinia";
export const useTokenStore = defineStore({
id: 'token',
state: () => ({
token: ''
}),
actions: {
setToken(newToken) {
this.token = newToken;
},
removeToken() {
this.token = '';
}
},
persist: true
});
工具类文件(utils文件夹)
request.js
//定制请求的实例
import axios from 'axios';
import { ElMessage } from 'element-plus'
//定义一个变量,记录公共的前缀 , baseURL
//const baseURL = 'http://localhost:8080';
const baseURL = '/api';
const instance = axios.create({ baseURL })
import { useTokenStore } from '@/stores/token.js'
//添加请求拦截器
instance.interceptors.request.use(
(config) => {
//请求前的回调
//添加token
const tokenStore = useTokenStore();
//判断有没有token
if (tokenStore.token) {
config.headers.Authorization = tokenStore.token
}
return config;
},
(err) => {
//请求错误的回调
Promise.reject(err)
}
)
/* import {useRouter} from 'vue-router'
const router = useRouter(); */
import router from '@/router/index.js'
//添加响应拦截器
instance.interceptors.response.use(
result => {
//判断业务状态码
if (result.data.code === 0) {
return result.data;
}
//操作失败
//alert(result.data.msg?result.data.msg:'服务异常')
ElMessage.error(result.data.msg ? result.data.msg : '密码错误')
//异步操作的状态转换为失败
return Promise.reject(result.data)
},
err => {
//判断响应状态码,如果为401,则证明未登录,提示请登录,并跳转到登录页面
if (err.response.status === 401) {
ElMessage.error('请先登录')
router.push('/login')
} else {
ElMessage.error('服务异常')
}
return Promise.reject(err);//异步的状态转化成失败的状态
}
)
export default instance;
其他文件
main.scss
body {
margin: 0;
background-color: #f5f5f5;
}
/* fade-slide */
.fade-slide-leave-active,
.fade-slide-enter-active {
transition: all 0.3s;
}
.fade-slide-enter-from {
transform: translateX(-30px);
opacity: 0;
}
.fade-slide-leave-to {
transform: translateX(30px);
opacity: 0;
}
尾声
用户模块的代码就这么多,后续主体板块会视想要实现的系统功能来进行更新。
GitHub 加速计划 / vu / vue
207.55 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:3 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 5 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献3条内容
所有评论(0)