vue2前台项目开发:第六章
一、完成注册部分
(1)获取验证码完成注册
首先把登录注册的静态页面搞过来,然后实现验证码部分,这里就是单纯的模拟一下,输入手机号,发送请求获取一个验证码,然后直接展示在文本框里,比较简单,就不多说了。
1.接口:
//10.获取验证码的接口
// /api/user/passport/sendCode/{phone}
export const reqRegisterCode = function(phone) {
return requests.get(`/user/passport/sendCode/${phone}`);
}
2.vuex:
async getRegisterCode({commit}, phone) {
try{
let result = await reqRegisterCode(phone);
commit('GETREGISTERCODE', result.data);
}catch(err) {
console.log(err.message);
}
},
3.双向绑定手机号,点击验证码按钮派发请求
getRegisterCode() {
//来个逻辑短路
this.phone && this.$store.dispatch('login/getRegisterCode', this.phone);
},
(2)完成注册用户业务
这部分也比较简单,主要是拿着手机号、验证码、密码去发送请求,添加到数据库。
1.接口
//11.注册用户的接口
// /api/user/passport/register
export const reqRegisterUser = (phone, password, code) => {
return requests({
method: 'post',
url: '/user/passport/register',
data: {
phone,
password,
code
}
})
}
2.vuex
async sendRegisterUser(context,{ phone, password, code}) {
console.log(context);
try {
let result = await reqRegisterUser(phone, password, code);
console.log(result);
if(result.code == 200) {
return '注册成功';
}
if(result.code == 223) {
return '该用户已注册!'
}
}catch(err) {
alert('请求失败',err.message);
}
}
3.点击注册按钮派发请求
data() {
return {
phone: '', //手机号
password: '', //密码
passwordConfirm: '', //确认密码
agree: false, //是否同意
}
},
.......
async completeRegister() {
try {
//来个逻辑短路
const {phone, password, passwordConfirm, agree, registerCode} = this;
if(phone&®isterCode&&password&&passwordConfirm&&password==passwordConfirm&&agree==true) {
let result = await this.$store.dispatch('login/sendRegisterUser', {phone, code:registerCode, password})
alert(result);
if(result == '注册成功') {
this.$router.push({
name: 'denglu'
})
}
}
}catch(err) {
alert('注册失败!',err)
}
},
二、登录
先click.prevent
阻止默认提交表单的操作,避免跳来跳去。复习阻止事件默认行为入口
(1)点击登录发送请求校验
然后写登录接口,点击登录时拿着用户名密码发请求校验:
1.接口
//12.登录接口
// /api/user/passport/login
export const reqUser = (phone, password) => {
return requests({
url: 'user/passport/login',
method: 'post',
data: {phone,password}
})
}
2.vuex
//2.登录
async userLogin(context, {phone,password}) {
let result = await reqUser(phone, password);
console.log('登录请求成功',result);
}
3.派发请求,路由跳转
userLogin() {
try {
let {phone,password} = this;
(phone&&password)&&this.$store.dispatch('login/userLogin',{phone, password});
this.$router.push('/home');
}catch(err) {
alert('登录请求失败!',err.message);
}
}
请求数据后,服务端会返回一个字段,名字叫token
(2)保存下发的token
当我们点击登录,返回的数据是这样的,里面有一个字段叫token
,它就是用户的唯一标识,将来我们请求用户相关的东西就要拿着这个token
。
由于vuex是非持久性存储数据,一刷新就没了,所以我们要把token
放在本地存储中
后面的每个请求都要和token有关,所以我们要把token写到请求头中
(3)拿着token请求用户数据并展示
这里有个问题,就是这个请求的派发应该写在哪里
1、如果只在home页写,那么跳转到其他页面点击刷新vuex中的用户数据就没了;但是如果每个用到用户名的组件都要派发,那就太麻烦了。
2、如果在app写,那么派发请求是在登录前,还没有token呢就请求不到数据,只有登录之后刷新页面(已经有token)才能请求到(刷新页面app肯定第一个挂载)
解决方案就是用路由守卫做判断,没有用户数据就派发请求。
这里我们先把派发home里。先把请求用户数据的接口写好:
//13.请求用户数据的接口
// /api/user/passport/auth/getUserInfo
export const reqUserInfo = () => {
return requests.get('/user/passport/auth/getUserInfo');
}
vuex保存用户数据到仓库。
//3.请求用户数据
async getUserInfo({commit}) {
let result = await reqUserInfo();
if(result.code == 200) {
console.log(result);
commit('GETUSERINFO',result.data);
}else {
console.log('请求用户信息失败,原因是:',result.message);
}
}
先在home页派发请求(实际是不对的,去别的页面刷新就没用户名了)
(4)退出登录
Header组件中,读取vuex的用户数据,拿到用户名
<p>尚品汇欢迎您!</p>
<p v-show="!userName">
<span>请</span>
<router-link to="/login">登录</router-link>
<router-link to="/register" class="register">免费注册</router-link>
</p>
<p v-show="userName">
<span>{{ userName }}</span>
<router-link to="/login" class="register" @click.native="logout">退出登录</router-link>
</p>
.......
<script>
computed: {
userName() {
return this.$store.state.login.userInfo.name;
}
}
</script>
<router-link>
添加点击事件(别忘了加上个native),删除仓库的用户数据,删除用户的token
//退出登录,删除用户数据,删除token,跳回登录页
logout() {
this.$store.state.login.userInfo = {}; //删除仓库数据,不知道直接这样好不好
localStorage.removeItem('token'); //删除token
}
(5)路由守卫(有点意思)
这里看起来比较绕,其实很简单,就三层逻辑
//前置路由守卫
router.beforeEach(async (to,form,next) => {
// 加了这个守卫,不写next(),就不会放行
let token = localStorage.getItem('token'); //读取token的值
//1.1用户是否登录(有没有token)
if(token) {
//2.1登录了就不能再回到登录页
if(to.path == '/login') {
next('/');
}
//2.2登陆了去其他的页面
else {
//3.1如果有用户数据,放行
if(store.state.login.userInfo.name) {
next();
}
//3.2如果没有用户数据,先请求成功再放行
else {
try {
//这个请求在挂载之前,所以刷新也会先请求
await store.dispatch('login/getUserInfo');
next();
}catch(err) {
console.log('请求用户数据失败!',err);
//这里还有一种情况,token过期请求不到
//那么就要清空token,重新登录
localStorage.removeItem('token');
next('/login');
}
}
}
}
//1.2如果没有登录
else {
//没登录不能去的路由地址
let pages = ['/trade','/pay','/paysuccess','/center/myorder'];
if(pages.includes(to.path)) {
//如果没登陆往这几个页面跳,就回到登录页,并传想去的页面的地址
//这样能提升用户体验,登录完成后直接跳到刚才的页面
next(`/login?redirect=${to.path}`);
}else {
next();
}
}
})
后面的支付部分我简单看了一下,比较简单,就是请求数据展示数据,elementUI展示收款二维码,收款反复发请求直到付款成功等,没有什么难点,就不做了。
完结撒花!!后面还会有更多项目的笔记,欢迎大家关注我和我一起攻克前端项目