首先说一下怎样写登陆注册功能:
我们之前是直接在Home.vue里面直接写主题代码,在APP.vue里面直接引入全部主题,但是显然这样是不符合实际情况的!所以我们需要写新的路由:
我们新的APP.vue:
<template>
<div >
<router-view />
</div>
</template>
<script>
export default {
name:"Layout",
}
</script>
然后我们新建一个框架层:也就是上面APP.vue引入的
<template>
<div>
<!-- 头部-->
<Header/>
<!-- 主体-->
<div style="display: flex">
<!-- 侧边栏-->
<Aside />
<!-- 内容区域-->
<router-view style="flex: 1"/>
</div>
</div>
</template>
<script>
import Header from "@/components/Header";
import Aside from "@/components/Aside";
export default {
name: "Layout.vue",
components:{
Header,
Aside
}
}
</script>
<style scoped>
</style>
接下来我们写登陆界面:
<template>
<div class="homepage-hero-module">
<div class="video-container">
<div :style="fixStyle" class="filter">
<div style="width: 400px; margin: 100px auto">
<div style="font-size: 30px; text-align: center; padding: 30px 0; color: #333">欢迎登录</div>
<el-form ref="form" :model="form" size="normal" :rules="rules">
<el-form-item prop="username">
<el-input v-model="form.username" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-icon :size="20">
<edit />
</el-icon>
<el-input v-model="form.password" show-password placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item>
<div style="display: flex">
<el-input prefix-icon="el-icon-key" v-model="form.validCode" style="width: 50%;" placeholder="请输入验证码"></el-input>
<ValidCode @input="createValidCode" />
</div>
</el-form-item>
<!-- <el-form-item>-->
<!-- <el-radio v-model="form.role" :label="1" style="color: white">管理员</el-radio>-->
<!-- <el-radio v-model="form.role" :label="2" style="color: white">普通用户</el-radio>-->
<!-- </el-form-item>-->
<el-form-item>
<el-button style="width: 100%" type="primary" @click="login">登 录</el-button>
</el-form-item>
<el-form-item><el-button type="text" @click="$router.push('/register')">前往注册 >> </el-button></el-form-item>
</el-form>
</div>
</div>
<video :style="fixStyle" autoplay loop muted class="fillWidth" v-on:canplay="canplay">
<source src="../assets/sea.mp4" type="video/mp4"/>
浏览器不支持 video 标签,建议升级浏览器。
</video>
</div>
</div>
</template>
<script>
import request from "@/utils/request";
import ValidCode from "@/components/ValidCode";
import { ArrowDown } from '@element-plus/icons-vue';
import {Share} from "@element-plus/icons";
export default {
name: "Login",
components: {
Share,
ValidCode,
ArrowDown
},
data() {
return {
vedioCanPlay: false,
fixStyle: '',
form: {role: 1},
rules: {
username: [
{required: true, message: '请输入用户名', trigger: 'blur'},
],
password: [
{required: true, message: '请输入密码', trigger: 'blur'},
],
},
validCode: ''
// 加背景图片
// bg: {
// backgroundImage: "url(" + require("@/assets/bg.jpg") + ")",
// backgroundRepeat: "no-repeat",
// backgroundSize: "100% 100%"
// }
}
},
mounted() {
sessionStorage.removeItem("user")
window.onresize = () => {
const windowWidth = document.body.clientWidth
const windowHeight = document.body.clientHeight
const windowAspectRatio = windowHeight / windowWidth
let videoWidth
let videoHeight
if (windowAspectRatio < 0.5625) {
videoWidth = windowWidth
videoHeight = videoWidth * 0.5625
this.fixStyle = {
height: windowWidth * 0.5625 + 'px',
width: windowWidth + 'px',
'margin-bottom': (windowHeight - videoHeight) / 2 + 'px',
'margin-left': 'initial'
}
} else {
videoHeight = windowHeight
videoWidth = videoHeight / 0.5625
this.fixStyle = {
height: windowHeight + 'px',
width: windowHeight / 0.5625 + 'px',
'margin-left': (windowWidth - videoWidth) / 2 + 'px',
'margin-bottom': 'initial'
}
}
}
window.onresize()
},
methods: {
canplay() {
this.vedioCanPlay = true
},
// 接收验证码组件提交的 4位验证码
createValidCode(data) {
this.validCode = data
},
login () {
this.$refs['form'].validate((valid) => {
if (valid) {
if (!this.form.validCode) {
this.$message.error("请填写验证码")
return
}
if(this.form.validCode.toLowerCase() !== this.validCode.toLowerCase()) {
this.$message.error("验证码错误")
return
}
request.post("/user/login", this.form).then(res => {
if (res.code === '0') {
this.$message({
type: "success",
message: "登录成功"
})
sessionStorage.setItem("user", JSON.stringify(res.data)) // 缓存用户信息
// 登录成功的时候更新当前路由
this.$router.push("/layout") //登录成功之后进行页面的跳转,跳转到主页
} else {
this.$message({
type: "error",
message: res.msg
})
}
})
}
})
}
}
}
</script>
<style scoped>
.homepage-hero-module,
.video-container {
position: relative;
height: 100vh;
overflow: hidden;
}
.video-container .poster img{
z-index: 0;
position: absolute;
}
.video-container .filter {
z-index: 1;
position: absolute;
/*background: rgba(0, 0, 0, 0.4);*/
width: 100%;
}
.fillWidth {
width: 100%;
}
</style>
注册界面:
<template>
<div style="width: 100%;background-color: orange; height: 100vh; overflow: hidden" >
<div style="width: 400px; margin: 100px auto">
<div style="font-size: 30px; text-align: center; padding: 30px 0">欢迎注册</div>
<el-form ref="form" :model="form" size="normal" :rules="rules">
<el-form-item prop="username">
<el-input prefix-icon="el-icon-user-solid" v-model="form.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input prefix-icon="el-icon-lock" v-model="form.password" show-password></el-input>
</el-form-item>
<el-form-item prop="confirm">
<el-input prefix-icon="el-icon-lock" v-model="form.confirm" show-password></el-input>
</el-form-item>
<el-form-item>
<el-button style="width: 100%" type="primary" @click="register">注册</el-button>
</el-form-item>
<el-form-item><el-button type="text" @click="$router.push('/login')"><<返回登录 </el-button></el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import request from "@/utils/request";
export default {
name: "Register",
data() {
return {
form: {},
rules: {
username: [
{required: true, message: '请输入用户名', trigger: 'blur'},
],
password: [
{required: true, message: '请输入密码', trigger: 'blur'},
],
confirm: [
{required: true, message: '请确认密码', trigger: 'blur'},
],
}
}
},
methods: {
register() {
if (this.form.password !== this.form.confirm) {
this.$message({
type: "error",
message: '2次密码输入不一致!'
})
return
}
this.$refs['form'].validate((valid) => {
if (valid) {
request.post("/user/register", this.form).then(res => {
if (res.code === '0') {
this.$message({
type: "success",
message: "注册成功"
})
this.$router.push("/login") //登录成功之后进行页面的跳转,跳转到主页
} else {
this.$message({
type: "error",
message: res.msg
})
}
})
}
})
}
}
}
</script>
<style scoped>
</style>
后端代码:
/**
* 用户登录
*/
@PostMapping("/login")
public Result<?> login(@RequestBody User user){
User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()).eq(User::getPassword, user.getPassword()));
if (res ==null){
return Result.error("-1","用户名或密码错误");
}
return Result.success();
}
/**
* 用户注册
*/
@PostMapping("/register")
public Result<?> register(@RequestBody User user){
User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, user.getUsername()));
if (res!=null){
return Result.error("-1","用户名重复");
}
if (user.getPassword()==null){
user.setPassword("123456");
}
userMapper.insert(user);
return Result.success();
}
前端路由:
import { createRouter, createWebHistory } from 'vue-router'
import Layout from '../layout/Layout.vue'
const routes = [
{
path: '/layout',
name: 'Layout',
component: Layout,
//重定向实现路由自动跳转:
redirect:"/home",
// 嵌套路由
children:[
{
path: '/home',
name: 'Home',
component: () => import("@/views/Home"),
}
]
},
{
path: '/login',
name: 'Login',
component: () => import("@/views/Login")
},
{
path: '/',
redirect:"/login",
},
{
path: '/register',
name: 'Register',
component: () => import("@/views/Register")
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
验证码插件:
<template>
<div
class="ValidCode disabled-select"
:style="`width:${width}; height:${height}`"
@click="refreshCode"
>
<span
v-for="(item, index) in codeList"
:key="index"
:style="getStyle(item)"
>{{ item.code }}</span>
</div>
</template>
<script>
export default {
name: 'ValidCode',
model: {
prop: 'value',
event: 'input'
},
props: {
width: {
type: String,
default: '100px'
},
height: {
type: String,
default: '40px'
},
length: {
type: Number,
default: 4
},
refresh: {
type: Number
}
},
data () {
return {
codeList: []
}
},
watch: {
refresh () {
this.createdCode()
}
},
mounted () {
this.createdCode()
},
methods: {
refreshCode () {
this.createdCode()
},
createdCode () {
const len = this.length
const codeList = []
const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789'
const charsLen = chars.length
// 生成
for (let i = 0; i < len; i++) {
const rgb = [Math.round(Math.random() * 220), Math.round(Math.random() * 240), Math.round(Math.random() * 200)]
codeList.push({
code: chars.charAt(Math.floor(Math.random() * charsLen)),
color: `rgb(${rgb})`,
fontSize: `${10 + (+[Math.floor(Math.random() * 10)] + 6)}px`,
padding: `${[Math.floor(Math.random() * 10)]}px`,
transform: `rotate(${Math.floor(Math.random() * 90) - Math.floor(Math.random() * 90)}deg)`
})
}
// 指向
this.codeList = codeList
// 将当前数据派发出去
// console.log(codeList.map(item => item.code).join(''))
this.$emit('input', codeList.map(item => item.code).join(''))
},
getStyle (data) {
return `color: ${data.color}; font-size: ${data.fontSize}; padding: ${data.padding}; transform: ${data.transform}`
}
}
}
</script>
<style scoped>
.ValidCode{
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.ValidCode span{
display: inline-block;
}
</style>
完结
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80999.html