登录注册业务
在尚品汇项目中
assets【放置静态资源文件的地方】
注册的业务
手机号:11
验证码:4-6
登录密码|确认密码:首字母大写、包含英文、数字、特殊字符等等。
获取验证码接口
/api/user/passport/sendCode/{phone}
有接口的话,都是一样的,现在api文件夹下的index.js书写方法,调用接口等
// 获取商品验证码 /api/user/passport/sendCode/{phone} method: 'get'
export const reqGetCode = (phone) => requests({
url: `/user/passport/sendCode/${phone}`,
method: 'get',
})
**在注册组件中我们需要实时获取到用户输入的手机号和服务器返回的验证码,所以我们需要使用到 ** v-model 来处理
同样的,除了手机号和验证码,密码和确认密码,以及是否同意都需要在data中设置定义
data() {
return {
// 收集表单数据 -- 手机号
phone: "",
// 验证码
code: "",
// 密码
password: "",
// 确认密码
password1: "",
// 是否同意
agree: true,
};
},
// 实时获取手机号
// 获取到了验证码在input框实时展示
书写完接口以后,我们要做的就是去store文件夹下书写vuex三连环 – 用户的登录注册业务逻辑重新用一个user文件夹

// 和之前的套路其实是一样的操作 我们一般都是在仓库中发请求
import { reqGetCode } from "@/api"
import { setToken, getToken, removeToken } from "@/utils/token"
// 登录与注册的模块
const state = {
code: ' ',
}
const mutations = {
GETCODE(state, code) {
state.code = code.data
}
}
const actions = {
// 获取验证码
async getCode({ commit }, phone) {
/*
获取验证码的这个接口,把验证码返回,但是正常情况下,后台把验证码发到用户手机上[省钱]
- 如果真是后台处理好了,下面就不用执行commit操作,用户看完会自己进行输入操作
*/
let result = await reqGetCode(phone)
// console.log(result)
if (result.status == 200) {
commit('GETCODE', result.data)
return 'OK'
} else {
return Promise.reject(new Error('fail'))
}
},
书写了actions以后需要在Register组件中进行相应的派发
Register组件的书写
methods: {
// $store.dispatch('getCode', phone)
// 获取验证码
async getCode() {
try {
// 简单判断一下 -- 至少要有数据
const { phone } = this;
phone && (await this.$store.dispatch("getCode", phone));
// this.$store.dispatch('getCode', this.phone)
// 如果获取到验证码:将组件的code属性变为仓库中的验证码,进行展示
// 验证码直接自己填写了
// console.log(this.$store);
// console.log(this.$store.state.user.code);
this.code = this.$store.state.user.code;
} catch (error) {
alert(error.message)
}
},
}
用户注册的接口 method:‘post’
url:/api/user/passport/register
书写调用接口方法
// 注册的接口
// url:/api/user/passport/register method:post phone code password(带的东西太多了,可以放到一个对象当中)
export const reqUserRegister = (data) => requests({
url: '/user/passport/register',
data,
method: 'post'
})
书写接口以后,在vuex中使用该接口,注册成功以后也不需要返回数据,不需要书写三连环
// 用户注册, 派发action, 然后进行发送请求的操作
// 也因为不需要返回数据,所以不需要接着上面书写三连环了
async userRegister({ commit }, user) {
let result = await reqUserRegister(user)
// console.log(result)
if (result.status == 200) {
return 'ok'
} else {
return Promise.reject(new Error('fail'))
}
},
同样需要在Register组件中派发该actions才行
// 用户注册
async userRegister() {
try {
const { phone, code, password, password1 } = this;
(phone && code && password == password1) && await this.$store.dispatch("userRegister", { phone, code, password });
// 如果成功,进行登录操作
this.$router.push('/login')
} catch (error) {
alert(error.message)
}
},
当你点击登录按钮的时候,需要把手机号、密码需要携带给服务器,服务器需要判断,你是不是我的用户【注册过的】
如果是用户登录成功,进行登录,如果用户登录失败给一个提示即可。
登录接口 - 接口书写完了以后,需要去仓库中发送请求,这一点很关键
url:'/api/user/passport/login' method:post phone password
export const reqUserLogin = (data) => requests({
url: '/user/passport/login',
data,
method: 'post'
})
token
登录业务的时候,我们需要明白是否登录成功,我们也是用async|await进行书写,
书写token.js来对token进行存储和获取操作 -一般放在utils工具包下面

// 因为是进行本次存储操作,所以对外暴露一个函数即可
// 对外暴露一个函数
// 存储TOKEN
export const setToken = (token) => {
localStorage.setItem('TOEKN', token)
}
// 获取TOKEN
export const getToken = () => {
localStorage.getItem('TOKEN')
}
// 删除token
export const removeToken = () => {
localStorage.removeItem('TOKEN')
}
书写登录业务 - 用户登录以后需要将token信息传入到state中
const state = {
code: '',
// token: '',
// token: localStorage.getItem('TOEKN'), // 其实状态下,就算是没存,相当于null值,但是在下一次刷新的时候就存了
token: getToken(),
}
const mutations = {
USERLOGIN(state, token) {
state.token = token
},
}
// 登录业务[token]
const actions = {
async userLogin({ commit }, data) {
// 需要的就是等待他成功的结果等 操作,这一点很关键 返回的结果就是登录成功或者是失败等
let result = await reqUserLogin(data)
// console.log(result)
// 服务器下发token,用户唯一标识符(uuid)
// 将来经常通过带token找服务器要用户信息进行相应展示
if (result.status == 200) {
// 用户已经登录成功且获取到了token
commit('USERLOGIN', result.data.data.token)
// 持久化存储token,因为token本身就是字符串的形式,所以不用转换
// localStorage.setItem('TOEKN', result.data.data.token)
setToken(result.data.data.token)
return 'ok'
} else {
return Promise.reject(new Error('fail'))
}
},
}
在Login登录组件中派发actions
// 登录的回调
async userLogin() {
try {
// alert(123) 同样的,在进行登录之前要拿到相应的东西 需要注意的一点就是vuex存储的数据不是持久化的
const { phone, password } = this;
(await this.$store.dispatch("userLogin", { phone, password })) && (phone && password)
// 登录成功 - 跳转到home首页
this.$router.push('/home')
} catch (error) {
alert(error.message)
}
},
重要问题
1、为什么刷新页面,用户信息就消失?
获取用户信息接口
URL:api/user/passport/auth/getUserInfo method: get
// 需要对接口操作的话,都是需要书写相应的方法的
// 获取用户信息【需要带着用户的token向服务器要用户信息】
// 没有参数的话还是使用请求头来进行携带操作
// URL:api/user/passport/auth/getUserInfo method: get
export const reqUserInfo = () => requests({
url: 'user/passport/auth/getUserInfo',
method: 'get'
})
我们需要在请求拦截器中,在请求头上面带上我们的token字段, - header上添加的字段不能是乱写的,应该和后台老师商量好
// 请求拦截器,在发请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情 请求拦截器在发送请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情,
requests.interceptors.request.use((config) => {
// console.log(store)
if(store.state.detail.uuid_token){
// 给请求头添加一个字段 和后台老师商量好了 userTempId 不能瞎写
config.headers.userTempId = store.state.detail.uuid_token
}
// 需要携带token带给服务器
if(store.state.user.token) {
// console.log('@@@')
config.headers.token = store.state.user.token
}
// 进度条开始动
nProgress.start()
// 请求拦截器中就算什么都不做的话,也需要返回一个配置对象,要不然会报错,config中包含headers
return config
})
在actions中调用接口,获取用户信息
// 获取用户登录信息
/* async getUserInfo({commit}) {
let result = await reqUserInfo() // 没有什么参数,发送请求的操作,应该在home组件中完成
// console.log(result)
if(result.status == 200) {
// 提交用户信息
commit('GETUSERINFO', result.data)
// 捞取用户信息,成功也可以,失败也可以
return 'ok'
}else {
return Promise.reject(new Error('fail'))
}
} */
async getUserInfo({ commit }) {
let result = await reqUserInfo() // 没有什么参数,发送请求的操作,应该在home组件中完成
console.log(result)
if (result.status == 200) {
// 提交用户信息
commit('GETUSERINFO', result.data.data)
// 捞取用户信息,成功也可以,失败也可以
}
},
用于登录操作会获取相应的信息,需要在mutations中进行展示
const state = {
userInfo: {}
}
const mutations = {
GETUSERINFO(state, userInfo) {
state.userInfo = userInfo
},
}
因为获取的用户信息是用户名等,在Home组件中进行展示,所以我们需要在Home组件中派发actions
this.$store.dispatch('getUserInfo')
最后我们需要在header组件中,显示用户信息

在组件中有用户名的时候显示一种状态,没有用户名的时候,显示另一种状态 使用 v-if & v-else
<!-- 没有用户的时候,进行显示即可 -->
<p v-if="!userName">
<span>请</span>
<router-link href="###" to="/login">登录</router-link>
<router-link href="###" class="register" to="/register"
>免费注册</router-link
>
</p>
<!-- 登录了 -->
<p v-else>
<a>{{ userName }}</a>
<a class="register" @click="logout">退出登录</a>
</p>

退出登录接口
/api/user/passport/logout
书写接口方法
// 退出登录 /api/user/passport/logout
export const reqLogout = () => requests({
url:'/user/passport/logout',
method:'get'
})
vuex中书写actions
// 退出登录
async userLogout({commit}) {
// 只是向服务器发起一次请求,通知服务器清楚token
let result = await reqLogout()
// 还需要清楚本地的一些内容
// 注意 action中不能操作state,我们必须提交到mutation修改state
if (result.status == 200) {
commit('CLEAR')
return 'ok'
} else {
return Promise.reject(new Error('fail'))
}
}
退出登录以后,我们需要对服务器中的数据进行相应的操作修改 mutations
const mutations = {
CLEAR(state) {
// 删除用户信息
state.token = ''
state.userInfo = {}
// 还需要清空本地存储的一些内容 token
removeToken()
}
}
然后在Header组件中点击退出登录,派发actions
<a class="register" @click="logout">退出登录</a>
// 退出登录
async logout() {
// 退出登录,需要做的事情
// 1、需要发请求,通知服务器退出登录【清除一些数据:token】
// 服务器肯定需要返回成功或者失败,尤其是删除成功以后还需要回到首页的操作
try {
await this.$store.dispatch("userLogout");
// 如果退出成功,回到首页
this.$router.push('/home')
} catch (error) {
alert(error.message);
}
// 2、清除项目当中的数据【userInfo、token】 因为下一次用户登录就是在此处
},