目录
网络请求
poist请求通过body主体发送 (对象)默认json 其他格式在transformRequest中配置
每次发送请求 携带token axios.interceptors.request.use配置 获取本地存储的token
接口需要在请求头中携带TOKEN信息
authorzation:token「客户端登录成功后存储在本地的令牌信息(从服务器获取)」
临时测试:生成的验证码可在「后端程序 -> code.txt」中查看
//获取验证码
export const PhoneCode = phone => {
return axios.post('/api/phone_code', {
phone
})
}
//登录
export const login = (phone, code) => {
return axios.post('/api/login ', {
phone,
code
})
}
//检测是否登录
export const CheckLogin = () => {
return axios.get('/api/check_login')
}
// 获取登录者信息
export const UserLnfo = () => {
return axios.get('/api/user_info')
}
-----------------------
axios.interceptors.request.use(config => {
// 设置请求头
config.headers['authorzation'] = localStorage.getItem("token");
return config;
});
vuex
存储用户信息和登录状态
单项数据流
state 存放数据
mutations修改state数据,,接收两个参数(state 仓库中的值, payload:要修改的值) 同步
actions 异步 获取数据 commit通知mutations修改数据 通过dispatch可以派发任务
import { createStore } from "vuex";
import { CheckLogin, UserLnfo } from '../api/index'
const store = createStore({
state: {
isLogin: null,
info: null
},
mutations: {
changeIsLogin(state, bool) {
state.isLogin = bool
},
changeInfo(state, payload) {
state.info = payload
}
},
actions: {
async changeIsLoginAsync({ commit }) {
let bool = false
let { code } = await CheckLogin()
if (code == 0) bool = true
commit('changeIsLogin', bool)
},
async changeInfoAstnc({ commit }) {
let { code, data } = await UserLnfo()
if (code == 0) {
commit('changeInfo', data)
}
}
},
})
export default store
封装标题栏
通过router跳转
<template>
<van-nav-bar :title="title" left-text="返回" left-arrow @click-left="onClickLeft"></van-nav-bar>
</template>
<script>
import { useRouter, useRoute } from 'vue-router'
export default {
name: 'Nav',
props: {
title: {
type: String,
default: ''
}
},
setup() {
//路由实例对象控制路由跳转
const router = useRouter()
//路由信息对象,获取路径参数
const route = useRoute()
//点击跳转返回上一级
const onClickLeft = (() => {
router.back()
})
return {
onClickLeft
}
}
}
</script>
<style lang="less" scoped>
/deep/ .van-icon,
/deep/ .van-nav-bar__text {
color: #000;
}
</style>
登录页
通过ref获取dom元素 创建ref实例对象赋值
vant form表单的使用
submit 事件可以通果校验后触发
每一项的表单项 有name属性可以指定校验项 (validate)
await formBox.value.validate("phone"); 返回对象为promise实例
rules校验规则 required 必填 message 提示信息 pattern通过正则校验
获取数据成功后开启定时器 禁用按钮 设置秒数
每次秒数减一 为0之后清除定时器 恢复禁用
校验通过后请求登录接口 失败清空输入框和校验规则
登录成功后 使用locationstore 存储token 配置请求头携带token
store.commit执行同步任务 修改登录状态 store.dispatch派发异步任务获取用户信息
<template>
<Nav></Nav>
<van-form ref="formBox" @submit="submit">
<van-cell-group inset>
<van-field
v-model="phone"
label="手机号"
label-width="50px"
name="phone"
:rules="[
{ required: true, message: '手机号为必填项哦~' },
{ pattern: regPhone, message: '手机号格式不对哦~' },
]"
>
<template #button>
<van-button
class="form-btn"
size="small"
type="primary"
@click="sendCode"
:disabled="!enable"
>{{ enable ? "发送验证码" : time }}
</van-button>
</template>
</van-field>
<van-field
v-model="code"
label="验证码"
label-width="50px"
:rules="[
{ required: true, message: '验证码为必填项哦~' },
{ pattern: regCode, message: '验证码必须是6位数字哦~' },
]"
></van-field>
</van-cell-group>
<div style="margin: 20px 40px">
<van-button round block type="primary" native-type="submit"
>立即登录/注册
</van-button>
</div>
</van-form>
</template>
<script>
import { reactive, toRefs, ref } from "vue";
import { Toast } from "vant";
import { useStore } from "vuex";
import { PhoneCode, login } from "../api/index";
import { useRouter } from "vue-router";
import Nav from "../components/Nav.vue";
export default {
name: "Login",
components: {
Nav,
},
setup() {
let state = reactive({
phone: "",
code: "",
enable: true,
time: "60s",
});
//获取form表单
let formBox = ref(null);
const store = useStore();
const router = useRouter();
//发送验证码
const sendCode = async () => {
try {
//校验手机格式
await formBox.value.validate("phone");
//发送请求
let { code } = await PhoneCode(state.phone);
if (code != 0) {
Toast("当前网略繁忙,请稍后重试");
return;
}
//开启按钮倒计时
state.enable = false;
let n = 60;
let timer = setInterval(() => {
n--;
if (n == 0) {
clearInterval(timer);
state.enable = true;
}
state.time = `${n}秒`;
}, 1000);
} catch (err) {}
};
//
const submit = async () => {
let { code, token } = await login(state.phone, state.code);
if (code != 0) {
Toast("小主,很遗憾,当前登录失败了~");
//重置表单检验&&清空数据
formBox.value.resetValidation();
state.code = "";
return;
}
//本地存储token(localStorage 页面关闭也会有)
localStorage.setItem("token", token);
//修改vuex登陆者状态 同步用commit
store.commit("changeIsLogin", true);
store.dispatch("changeInfoAstnc");
Toast("小主,当前登录成功哦~");
router.back();
};
return {
...toRefs(state),
regPhone: /^(?:(?:\+|00)86)?1\d{10}$/,
regCode: /^\d{6}$/,
formBox,
sendCode,
submit,
};
},
};
</script>
<style lang="less" scoped>
.van-form {
margin-top: 30px;
}
.form-btn {
width: 78px;
}
</style>