一、登录注册静态组件引入
在样式当中也可以使用@符号,但要加
~@/
二、注册业务
1、验证码功能
用v-model动态绑定用户输入的手机号和验证码
<input placeholder="请输入你的手机号" v-model="phone"/>
<input placeholder="请输入你的验证码" v-model="code"/>
data() {
return {
phone: '', //phone numbers
code: '', //code numbers
};
},
2、获取验证码接口
因为接口文件里有获取验证码的接口,在这我们要写接口,分析一下要返回的数据,输入手机号,应该返回一个code,也就是验证码
//获取验证码
//URL:/api/user/passport/sendCode/{phone} method:get
export const reqGetCode = (phone) =>
requests({
url: `/user/passport/sendCode/${phone}`,
method: "get"
});
写仓库
import { reqGetCode } from '@/api';
const state = {
code: '',
};
const actions = {
//获取验证码
async getCode({ commit }, phone) {
let result = await reqGetCode(phone);
// console.log(result);
if (result.code == 200) {
commit('GETCODE', result.data);
}
},
}
const mutations = {
GETCODE(state, code) {
state.code = code;
},
};
const getters = {};
export default {
state,
actions,
mutations,
getters,
};
在获取密码这定义点击事件
<button style="width:100px;height:38px" @click="getCode">获取验证码</button>
data() {
return {
phone: '', //phone numbers
code: '', //code numbers
password: '', //password numbers
password1: '', //sure password
agree: true, //agree
};
},
methods: {
// 获取验证码
async getCode() {
try {
const { phone } = this; //解构以后就不用写this了
phone && (await this.$store.dispatch('getCode', phone));
//将组件的code属性值变为仓库中验证码[验证码直接自己填写了]
this.code = this.$store.state.user.code;
} catch (error) {
console.log(error.message);
}
},
}
通过v-model绑定数据
3、完成注册
当用户点击注册,应该是转跳到登录页面,
<button @click="userRegister">完成注册</button>
然后要用到注册用户接口
//注册
//url:/api/user/passport/register method:post phone code password
export const reqUserRegister = (data) =>
requests({
url: "/user/passport/register",
data,
method: "post"
});
import { reqUserRegister } from '@/api';
//注册
async userRegister({ commit }, user) {
let result = await reqUserRegister(user);
// console.log(result);
if (result.code == 200) {
return 'ok';
} else {
return Promise.reject(new Error('faile'));
}
},
// 点击完成注册
async userRegister() {
const success = await this.$validator.validateAll();
//全部表单验证成功,在向服务器发请求,进行祖册
//只要有一个表单没有成功,不会发请求
if (success) {
try {
const { phone, code, password, password1 } = this;
await this.$store.dispatch("userRegister", {
phone,
code,
password,
});
//注册成功进行路由的跳转
this.$router.push("/login");
} catch (error) {
alert(error.message);
}
}
},
三、登录业务
1. 登录
第一步肯定就是接口了
//登录
//URL:/api/user/passport/login method:post phone password
export const reqUserLogin = (data) =>
requests({
url: "/user/passport/login",
data,
method: "post"
});
import { reqUserLogin } from '@/api';
//登录业务
async reqUserLogin({ commit }, user) {
let result = await reqUserLogin(user);
console.log(result);
},
<button class="btn" @click="userLogin">登 录</button>
当我们绑定了点击事件,会发现点击登录,url地址栏会转跳,所以要阻止默认行为
prevent
:阻止事件默认行为
stop
:阻止事件冒泡
once
:事件执行一次
<button class="btn" @click.prevent="userLogin">登 录</button>
登录成功的时候,后台为了区分你这个用户是谁,服务器会下发token【令牌:唯一标识符】
登录接口:一般登录成功服务器会下发token,前台持久化存储token,是通过token找用户账号密码,而不是直接获取
//登录业务
async reqUserLogin({ commit }, user) {
let result = await reqUserLogin(user);
// console.log(result);
//服务器下发token,用户唯一标识符(uuid)
//将来经常通过带token找服务器要用户信息进行展示
if (result.code === 200) {
commit('USERLOGIN', result.data.token);
return "ok"
}else{
return Promise.reject(new Error("faile"));
}
},
const mutations = {
USERLOGIN(state, token) {
state.token = token;
},
};
const state = {
token: getToken(),
};
但是这的token当你一刷新就没了,就还需要持久化存储token
第一种方法:加一条localStorage.setItem
//登录业务
async reqUserLogin({ commit }, user) {
let result = await reqUserLogin(user);
// console.log(result);
//服务器下发token,用户唯一标识符(uuid)
//将来经常通过带token找服务器要用户信息进行展示
if (result.code === 200) {
commit('USERLOGIN', result.data.token);
localStorage.setItem("TOKEN",result.data.token);//持久化存储token
}
},
第二种方法:
在utils中添加一个token.js文件
// 对外暴露一个函数存储token
export const setToken = (token) => {
localStorage.setItem('Token', token);
};
//对外暴露一个函数获得token
export const getToken = () => {
return localStorage.getItem('Token');
};
然后回到仓库使用
import { setToken } from '../utils/token';
const state = {
code: '',
token: getToken(),
userInfo: {},
};
//登录业务
async reqUserLogin({ commit }, user) {
let result = await reqUserLogin(user);
// console.log(result);
//服务器下发token,用户唯一标识符(uuid)
//将来经常通过带token找服务器要用户信息进行展示
if (result.code === 200) {
commit('USERLOGIN', result.data.token);
setToken(result.data.token); //持久化存储token
}
},
2. 退出登录
退出登录需要做的事情
- 需要发请求,通知服务器退出登录【清楚一些数据:token】
- 清楚项目当中的数据【userInfo、token】
先绑定退出登录按钮
<a @click="logOut">退出登录</a>
第一步还是一样,写api
//退出登录
//URL:/api/user/passport/logout get
export const reqlogout = () =>
requests({
url: "/user/passport/logout",
method: "get"
});
然后三连环写仓库,这里要actions告知mutations才能修改state,actions里面不能直接改state
import { removeToken } from '../utils/token';
const state = {
code: '',
token: getToken(),
userInfo: {},
};
const mutations = {
CLEAR(state) {
//帮仓库中先关用户信息清空
state.userInfo = {};
state.token = '';
//本地存储数据清空
removeToken();
},
};
const actions = {
/ 退出登录
async logout({ commit }) {
//只是向服务器发起一次请求,通知服务器清除token
let result = await reqlogout();
// console.log(result);
//action里面不能操作state,提交mutation修改state
if (result.code == 200) {
commit('CLEAR', result.data);
} else {
return Promise.reject(new Error('falie'));
}
},
};
把清空token封装到了token.js文件中
// 对外暴露一个函数清空token
export const removeToken = () => {
return localStorage.removeItem('Token');
};
当用户是在搜索页面退出了登录,那应该返回home页面
// 点击退出登录
logOut() {
//退出登录需要做的事情
//1:需要发请求,通知服务器退出登录【清除一些数据:token】
//2:清除项目当中的数据【userInfo、token】
try {
this.$store.dispatch('logout');
// 跳转到首页
this.$router.push('/home');
} catch (error) {
console.log(error.message);
}
},
四、存在的问题
1. 多个组件展示用户信息需要在每一个组件的mounted中触发this.$store.dispatch(‘getUserInfo’);
当我们转跳到别的页面的时候,发现登录的信息又没了,因为当初我们只在home页面上添加了回调函数,那这要怎么办呢
那放在App.vue
里呢?还是会有缺陷,第一次没有登录信息
2. 用户已经登陆了,就不应该再回登录页
还有一个问题,当用户登录了,他还在url地址栏输入返回login,那这还能让他返回login页面吗