一. 整体分析
在本项目中, 登录不是必需的,但是,如果你不登录的话就是一个普通的游客,而不能享受登录用户的功能,例如:不能发布留言
思路
-
创建页面级组件并配置路由,能通过路由地址来访问它
-
布局结构,用vant的组件来实现基本布局
-
调整样式,根据需要自已写样式来覆盖vant组件库的样式
-
实现业务功能 :
1.1 表单校验
1.2 调用接口,发登录请求
1.3 根据反馈结果,给出提示
二. 创建页面并配置路由
创建页面,并能通过路由地址来访问
1. 创建组件
在src/views/login/login.vue写入 :
<template>
<div class="login">
登录
</div>
</template>
<script>
export default {
name: 'Login'
}
</script>
复制代码
组件的布局,在后面来做
2. 配置路由
在 router/index.js
中配置路由表 :
{
path: '/login',
name: 'login',
// component: Login
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "login" */ '../views/login/login.vue')
}
复制代码
3. 在根组件app.vue配置路由容器
去掉其它的用于测试按钮组件,只留下router-view:路由的出口
<template>
<div id="app">
<!-- 路由出口 -->
<router-view></router-view>
</div>
</template>
复制代码
4. 测试
访问 /login
查看是否能访问到登录页面组件
5. 易错点
- 在app.vue中,router-view不能删除
<!-- 路由出口 -->
<router-view/>
复制代码
- 现在没有配置主页,所以localhost:8080没有东西
三. 实现布局结构
使用vant组件库中的组件来“画页面”
这里主要使用到三个 Vant 组件:
在login.vue将登录页修改为
<template>
<div>
<!-- 1. nav-bar -->
<van-nav-bar
title="黑马头条"
/>
<!-- 2. 表单登录 -->
<van-form @submit="onSubmit">
<van-field
v-model="username"
name="用户名"
label="用户名"
placeholder="用户名"
/>
<van-field
v-model="password"
type="password"
name="密码"
label="密码"
placeholder="密码"
/>
<div style="margin: 16px;">
<van-button block type="info" native-type="submit">提交</van-button>
</div>
</van-form>
</div>
</template>
<script>
export default {
name: 'login',
data () {
return {
username: '',
password: ''
}
},
methods: {
onSubmit (values) {
console.log('submit', values)
}
}
}
</script>
复制代码
四. 样式处理
原则:
-
把设置登录页头部的样式写到全局(全局生效),因为其它页面组件中也要使用。
-
把非公共样式写到页面组件内部,避免和其它组件样式冲突。
设置全局样式
实现在其他页面的头部的区域样式也能复用
1. 创建 styles/index.less
写入全局样式
// 全局样式
.van-nav-bar{
background-color: #3196fa;
.van-nav-bar__title {
color:#fff;
}
}
复制代码
用自已写的样式来覆盖vant自带的样式,最后要实现顶部.van-nav-bar的样式
2. 在 main.js
中引入
// 引入全局样式
import '@/styles/index.less'
复制代码
添加局部样式
设置登录按钮的样式,将 views/login/login.vue
组件中的 style 修改为:
<style lang="less" scoped>
// 按钮
.btn-wrap {
padding:20px;
.van-button{
width: 100%;
background-color: #6db4fd;
color:#fff;
}
}
</style>
复制代码
最终效果
五. 登录页-数据绑定
根据接口要求绑定在表单元素上做双向绑定
1. 补充数据项
export default {
data () {
return {
user: {
mobile: '13800000002', // 测试账号可以登录
code: '246810'
}
}
}
}
</script>
复制代码
2. 在表单中使用 v-model
做数据绑定
<van-cell-group>
<van-field label="手机号" v-model.trim="user.mobile" placeholder="请输入手机号" />
</van-cell-group>
<van-cell-group>
<van-field label="密码" v-model.trim="user.code" type="password" placeholder="请输入密码" />
</van-cell-group>
复制代码
.trim修饰符,用来去掉左右的空格
3. 测试效果
在浏览器使用 VueDevtools 调试工具查看是否绑定成功
六. 登录页-表单验证
使用vant
组件库自带的表单校验功能,完成登录表单校验
规则:手机号必须是合法的; 密码必须是6位数字
van-form中的表单校验
vant自带的表单验证功能 :
<van-form @failed="onFailed" @submit="onSubmit">
<!-- 通过 pattern 进行正则校验 -->
<van-field
v-model="value1"
name="pattern"
placeholder="正则校验"
:rules="[{ pattern, message: '请输入正确内容' }]"
/>
<!-- 通过 validator 进行函数校验 -->
<van-field
v-model="value2"
name="validator"
placeholder="函数校验"
:rules="[{ validator, message: '请输入正确内容' }]"
/>
<!-- 通过 validator 进行异步函数校验 -->
<van-field
v-model="value3"
name="asyncValidator"
placeholder="异步函数校验"
:rules="[{ validator: asyncValidator, message: '请输入正确内容' }]"
/>
<div style="margin: 16px;">
<van-button round block type="info" native-type="submit">提交</van-button>
</div>
</van-form>
复制代码
vant官网表单验证链接: vant-contrib.gitee.io/vant/#/zh-C…
总结:van-form中的表单校验的要点是:
- 表单验证成功或者失败的事件:failed, submit (加在van-form上)
- 表单元素的验证时机: validate-trigger, 默认是onblur:失去焦点时验证 (加在van-form上)
- 验证规则添加在具体的表单元素上
代码
<template>
<div class="login">
<van-nav-bar title="用户登录" />
<van-form
@failed="onFailed"
@submit="onSubmit"
>
<!-- 表单区域 -->
<van-cell-group>
<van-field
v-model.trim="user.mobile"
type="tel"
label="手机号"
:rules="[{ pattern: /^1\d{10}$/, message: '请输入正确的手机号'}]"
/>
<van-field
v-model.trim="user.code"
type="password"
label="密码"
:rules="[{ pattern: /^\d{6}$/, message: '请输入正确的密码'}]"
/>
</van-cell-group>
<!-- 按钮 -->
<!-- @click="hLogin" -->
<!-- 在form中按钮在点击时,是否默认具备提交表单的功能? -->
<div class="btn-warp">
<van-button type="info">登录</van-button>
</div>
</van-form>
</div>
</template>
<script>
export default {
data () {
return {
user: {
mobile: '13911111111', // 初始帐号
code: '246810' // 固定密码
}
}
},
methods: {
onSubmit () {
console.log('验证成功')
this.doLogin()
},
onFailed () {
console.log('验证失败')
},
doLogin () {
// 做具体的登录功能
}
}
}
</script>
复制代码
七. 登录-发ajax请求做登录
通过ajax请求做登录功能
-
按接口文档要求和axios的格式来完成代码
-
先去封装用户登录方法,然后在login.vue中调用
import { ajax } from '@/utils/request.js'
doLogin () {
request({
url: '/v1_0/authorizations',
method: 'POST',
data: {
mobile: this.user.mobile,
code: this.user.code
}
}).then(res => {
// 根据请求的返回结果,做后续的处理
})
}
复制代码
在network查看效果
- 对于跨域的复杂请求(有自己额外的请求头,请求头的content-type是application/json),浏览器会发出一个预检请求,成功之后,再发具体的ajax请求。(前端不需要任何事)
八. 登录-loading 效果
通过vant中提供的toast.success, $toast.fail来提升用户交互体验
toast组件
因为我们全局安装了vant, 所以 this.$toast 可以直接在任意组件中使用
格式
this.$toast.loading({
duration: 0, // 持续展示 toast,永远不会关闭
overlay: true, // 整体添加一个遮罩
message: '加载中...'
})
this.$toast.success('成功')
this.$toast.fail('失败')
复制代码
参考代码
async doLogin () {
try {
this.$toast.loading({
duration: 0, // 持续展示 toast,永远不会关闭,它会被后续的toast覆盖
overlay: true, // 整体添加一个遮罩
message: '加载中...'
})
// 发请求
const res = await login()
// 关闭loading
this.$toast.success('欢迎' + this.user.code)
} catch(err) {
console.log(err)
this.$toast.fail('登录失败了')
}
}
复制代码
- 把网络速度调整慢一些可以看到效果
- 换一个验证码,可以模拟登录失败的情况
小结
ajax操作时,需要给出必要的交互提示。
由于我们引入vant,并是完整引入 ,所以vant会在Vue的原型上添加$toast方法(这个方法不是vue自带,是vant组件库提供的)