Vue项目——用户登录
创建组件并配置路由首先我们创建了一个登录组件 src/views/login/index.vue将登陆页面组件配置到路由中const routes = [{path: '/login',name: 'login',component: () => import('@/views/login')}]这里给大家普及一个小知识:在 VueCLI创建的项目中 @ 表示 src 目录...
创建组件并配置路由
首先我们创建了一个登录组件 src/views/login/index.vue
将登陆页面组件配置到路由中
const routes = [
{
path: '/login',
name: 'login',
component: () => import('@/views/login')
}
]
这里给大家普及一个小知识:
在 VueCLI创建的项目中 @ 表示 src 目录
它是 src 目录的路径别名
好处:它不受当前文件路径的影响
注意:@就是src路径,后面别忘了写那个斜杠
使用建议:如果加载的资源路径就在当前目录下,那就正常写
如果需要进行父级路径查找的都使用@
页面布局
实现页面基本样式 和结构(使用了element-ui的表单组件)来完页面的结构和样式
实现基本登录功能
思路:
- 给登陆按钮注册点击事件
- 获取表单数据
- 请求登录
- 处理后端响应结果
-
- 成功处理
-
- 失败处理
登录消息提示
需要将方法挂载到原型上面在使用
import Vue from 'vue'
import {Message } from 'element-ui'
Vue.prototype.$message = Message
登录中 loading 提示
两个作用:
- 防止网络请求慢出现用户多次点击触发登录请求
-
- 一种方式是在请求期间把交互按钮禁用不允许被点击
-
- 一种方式就是展示 loading 不允许被点击
- 交互反馈
1、在 data 中添加数据用来控制登录按钮的 loading 状态
2、给登录按钮绑定 loading 状态
表单验证
Form 组件提供了表单验证的功能,只需要通过 rules
属性传入约定的验证规则,并将 Form-Item 的 prop
属性设置为需校验的字段名即可
下面是内置的基本验证规则:
规则 | 说明 |
required | 必须的,例如校验内容是否非空 |
pattern | 正则表达式,例如校验手机号码格式、校验邮箱格式 |
range | 使用 min 和 max 属性定义范围。对于字符串和数组类型,将根据长度进行比较,对于数字类型,数字不得小于 min,也不得大于 max。 |
len | 要验证字段的确切长度,请指定 len 属性。对于字符串和数组类型,对 length 属性执行比较,对于数字类型,此属性指示数字的完全匹配,即,它可能仅严格等于 len。如果 len 属性与最小和最大范围属性组合,则 len 优先。 |
enum | 要从可能值列表中验证值,请使用带枚举属性的枚举类型,列出该字段的有效值,例如: |
如果内置的校验规则不满足,也可以自定义校验规则
1、给 el-from 组件绑定 model 为表单数据对象
2、给需要验证的表单项 el-form-item 绑定 prop 属性
- 注意:prop 属性需要指定表单对象中的数据名称
3、通过 el-from 组件的 rules 属性配置验证规则
4、ref 的作用主要用来获取表单组件手动触发验证
封装请求模块
对于项目中的请求操作:
- 接口请求可能需要重用
- 实际工作中,接口非常容易变动,改起来麻烦
我们建议的做法是把所有的请求都封装成函数然后统一的组织到模块中进行管理,这样做的好处就是:管理维护更方便,也好重用。
下面是我们优化封装请求的具体操作。
1、创建 src/api/user.js
,封装登录请求方法
// 用户相关的接口调用
import request from '@/utils/request.js'
// 登录功能
const userLogin = data => {
return request.post('/mp/v1_0/authorizations', data)
}
export { userLogin }
代码
<template>
<div class="box">
<div class="login-form-wrap">
<div class="login-head">
<div class="logo"></div>
</div>
<el-form ref="userForm" :rules="rules" :model="user">
<el-form-item prop="mobile">
<el-input v-model="user.mobile" placeholder="请输入手机号"></el-input>
</el-form-item>
<el-form-item prop="code">
<el-input v-model="user.code" placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item prop="agree">
<el-checkbox v-model="user.agree"
>我已阅读并同意用户协议和隐私条款</el-checkbox
>
</el-form-item>
<el-form-item>
<!-- loading 让按钮进入登录中的状态 不可点击 增加交互效果 -->
<el-button type="primary" @click="onLogin" :loading="loginLoading"
>登录</el-button
>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
// 引入登录接口方法
import { userLogin } from '@/utils/user.js'
export default {
name: 'Login',
data () {
// 自定义验证规则函数
const validateAgree = (rule, value, callback) => {
if (value) {
callback()
} else {
callback(new Error('请勾选同意协议'))
}
}
return {
// 表单数据
user: {
mobile: '13911111111',
code: '246810',
agree: false
},
// 是否勾选
loginLoading: false, // loading... 一开始是没有的 只在登录的过程中为true
// 表单验证规则
rules: {
mobile: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{
pattern: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
message: '请输入正确的号码格式',
trigger: 'blur'
}
],
code: [
{ required: true, message: '请输入验证码', trigger: 'blur' },
{ pattern: /\d{6}$/, message: '请输入正确的验证码格式', trigger: 'blur' }
],
agree: [{ validator: validateAgree, trigger: 'change' }]
}
}
},
methods: {
// 登录按钮绑定事件
onLogin () {
this.$refs.userForm.validate(async valid => {
// 如果验证失败,不发送请求 结束函数
if (!valid) return false
// 验证通过 是按钮进入 loading... 登录中状态
this.loginLoading = true
// 调用登录接口 使用await优化 拿到返回的结果
const data = await userLogin(this.user).catch(err => {
this.$message.error('登录失败手机号或验证码错误')
return err
})
if (data.status !== 201) return
this.$message.success('登录成功')
})
// 登录调用完成 让按钮恢复
this.loginLoading = false
}
}
}
</script>
<style lang="less" scoped>
.box {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
background: url('');
background: url('./login_bg.jpg') no-repeat;
background-size: cover;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.login-form-wrap {
background: white;
min-width: 400px;
padding: 30px 50px 10px;
background-color: #fff;
}
.login-head {
display: flex;
justify-content: center;
margin-bottom: 20px;
}
.logo {
width: 200px;
height: 57px;
background: url('./logo_index.png') no-repeat;
background-size: contain;
}
.el-button {
width: 100%;
}
</style>
更多推荐
所有评论(0)