目录
1.前言
2.表单
3.容器
4.路由
5.校验
6.请求后端接口
1.前言
本文是博主vue实战项目系列文章的第一篇,本系列将清晰的从搭建环境开始一步步开发一个vue的通用管理系统,项目规模不大,较为小巧,但是覆盖了目前常用的前端开发技术。很适合作为一个前端的练习项目,也特别适合后端的小伙伴用来熟悉前端。整个系列走完,会对当前的前端开发的技术栈有了较为大致的了解,不会再打开现在的一个前端项目两眼一抹黑。
本项目会先用vue2来开发,然后升级成vue3,前置的环境准备等相关内容请移步:
从0开始搭建一个前端项目的架子-CSDN博客
2.表单
一个登录页由哪些东西构成?无非就是最核心的输入用户名密码的输入框,再加上一些杂七杂八的修饰元素。比如我们常见的QQ邮箱的页面:
输入用户名密码的地方很明显是一个表单,作为整个登录页的核心,这个输入框表单当然是我们要首先写出来的。要是用原生HTML来写的话,还要自己手动编写很多关于样式的内容,太麻烦了,UI框架的好处就体现出来了,自带的一系列带样式的组件,拿来就用,既然本项目选择了elementUI来作为UI框架,直接去elementUI官网上去拿一个自己看得上的表单组件即可:
我看上了这个表单:
于是直接展开它的代码,把其中要的表单组件的代码拷贝出来新建一个Login组件即可。
我们要拷贝的代码:
<el-form :label-position="labelPosition" label-width="80px" :model="formLabelAlign">
<el-form-item label="名称">
<el-input v-model="formLabelAlign.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-input v-model="formLabelAlign.region"></el-input>
</el-form-item>
<el-form-item label="活动形式">
<el-input v-model="formLabelAlign.type"></el-input>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
labelPosition: 'right',
formLabelAlign: {
name: '',
region: '',
type: ''
}
};
}
}
</script>
新建一个Login组件:
稍微调整一下Login组件的内容,将这个表单组件调整为,我们要的输入用户名、密码的输入框,主要就是改一下输入框的名字,改一下数据的名字:
<template>
<el-form
label-width="80px"
:model="form"
ref="form"
:rules="rules"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="login('form')">登录</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
form: {
username: "",
password: "",
}
}
}
};
</script>
3.容器
光有了输入框表单,我们可以启动来看看是什么样子:
组件直接铺满了屏幕,这显然不是我们想要的是前面看到的那种类似于QQ邮箱登录页那种输入框的效果。我们需要找一个容器来将输入框表单装起来,elementUI提供了卡片容器可以实现这种效果:
把代码扣下来,将输入框放进卡片容器中。
代码示例:
<template>
<div class="login">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>通用后台管理系统</span>
</div>
<el-form
label-width="80px"
:model="form"
ref="form"
:rules="rules"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="login('form')">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
效果:
调整一下整体的CSS:
<style lang="less">
.login{
width: 100%;
height:100%;
position: absolute;
background: #409EFF;
.box-card{
width:450px;
margin: 200px auto;
.el-card__header{
font-size: 30px;
}
.el-button{
width: 100%;
}
}
}
</style>
效果:
4.路由
登录页应该作为系统的默认首页,所以我们需要配置好路由:
让访问/和/login的请求都转跳到登录页上。
5.校验
登录页的输入框应该有合理的输入校验,对输入的用户名、密码进行校验,对于不合法的输入,应该弹出提示。elementUI的表单组件是允许在标签上配置校验规则的:
<template>
<div class="login">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>通用后台管理系统</span>
</div>
<el-form
label-width="80px"
:model="form"
ref="form"
>
<el-form-item label="用户名" prop="username"
:rules="[{required:true,message:'请输入用户名',trigger:'blur'}]">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password"
:rules="[{required:true,message:'请输入用户名',trigger:'blur'}]"
>
<el-input type="password" v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="login('form')">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
form: {
username: "",
password: "",
},
};
},
methods:{
login(form){
this.$refs[form].validate((valid=>{
if(valid){
console.log(this.form)
}else{
console.error(this.form)
}
}))
}
}
};
</script>
<style lang="less">
.login{
width: 100%;
height:100%;
position: absolute;
background: #409EFF;
.box-card{
width:450px;
margin: 200px auto;
.el-card__header{
font-size: 30px;
}
.el-button{
width: 100%;
}
}
}
</style>
优化校验规则:
原来的校验规则是在输入框上单独写,这样代码不好维护,elementUI支持将校验规则抽出来,在表单上以:rules="rules"的方式来引用,这样可以将规则集中写在数据域里,便于维护。这些elementUI支持的校验规则和标签上的扩展属性可以翻看elementUI的官方文档。
<template>
<div class="login">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>通用后台管理系统</span>
</div>
<el-form
label-width="80px"
:model="form"
ref="form"
:rules="rules"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="login('form')">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
export default {
data() {
//elementUI支持在数据校验时传三个参数,规则、输入参数、回调函数
const validData=(rule,value,callback)=>{
if(value===''){
callback(new Error('输入不能为空'))
}else{
callback()
}
}
return {
form: {
username: "",
password: "",
},
rules:{
username:[{validator:validData,trigger:'blur'}],
password:[{validator:validData,trigger:'blur'}]
}
};
}
};
</script>
<style lang="less">
.login{
width: 100%;
height:100%;
position: absolute;
background: #409EFF;
.box-card{
width:450px;
margin: 200px auto;
.el-card__header{
font-size: 30px;
}
.el-button{
width: 100%;
}
}
}
</style>
效果:
6.请求后端接口
最后我们使用axios加上对后端接口的请求,home页面暂时还未开发,直接转跳到HelloWorld组件上去即可:
<template>
<div class="login">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>通用后台管理系统</span>
</div>
<el-form
label-width="80px"
:model="form"
ref="form"
:rules="rules"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="form.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="login('form')">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
export default {
data() {
//elementUI支持在数据校验时传三个参数,规则、输入参数、回调函数
const validData=(rule,value,callback)=>{
if(value===''){
callback(new Error('输入不能为空'))
}else{
callback()
}
}
return {
form: {
username: "",
password: "",
},
rules:{
username:[{validator:validData,trigger:'blur'}],
password:[{validator:validData,trigger:'blur'}]
}
};
},
methods:{
login(form){
this.$refs[form].validate((valid=>{
if(valid){
console.log(this.form)
this.$router.push('/home')
this.axios.post('https://rapserver.sunmi.com/app/moc/340/login',this.form)
.then(res=>{
console.log(res)
if(res.data.status===200){
localStorage.setItem('username',res.data.username)
this.$message({message:res.data.message,type:'success'})
this.$router.push('/home')
}
})
}else{
console.error(this.form)
}
}))
}
}
};
</script>
<style lang="less">
.login{
width: 100%;
height:100%;
position: absolute;
background: #409EFF;
.box-card{
width:450px;
margin: 200px auto;
.el-card__header{
font-size: 30px;
}
.el-button{
width: 100%;
}
}
}
</style>