

目录
本文是博主vue实战项目系列文章的第一篇,本系列将清晰的从搭建环境开始一步步开发一个vue的通用管理系统,项目规模不大,较为小巧,但是覆盖了目前常用的前端开发技术。很适合作为一个前端的练习项目,也特别适合后端的小伙伴用来熟悉前端。整个系列走完,会对当前的前端开发的技术栈有了较为大致的了解,不会再打开现在的一个前端项目两眼一抹黑。
本项目会先用vue2来开发,然后升级成vue3,前置的环境准备等相关内容请移步:
一个登录页由哪些东西构成?无非就是最核心的输入用户名密码的输入框,再加上一些杂七杂八的修饰元素。比如我们常见的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>
光有了输入框表单,我们可以启动来看看是什么样子:

组件直接铺满了屏幕,这显然不是我们想要的是前面看到的那种类似于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:
- .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%;
- }
-
- }
- }
效果:

登录页应该作为系统的默认首页,所以我们需要配置好路由:
让访问/和/login的请求都转跳到登录页上。

登录页的输入框应该有合理的输入校验,对输入的用户名、密码进行校验,对于不合法的输入,应该弹出提示。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'}]
- }
- };
- },
- 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>
效果:

最后我们使用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>