Vue-Axios的封装---登录注册---axios(二)
Vue-cli---Axios的封装简单的的登录与注册第一种---逻辑数据未分离注册登录用户页面获取用户数据信息以及注销第二种---逻辑数据分离---token封装Axios调用封装完毕的Axios---并在添加所需要的方法然后进行使用登录zai首页获取并显示用户信息及注销token的使用简单的的登录与注册第一种—逻辑数据未分离注册使用注册原型的方式的axios方法进行注:有后台更好<tem
·
Vue-cli---Axios的封装
简单的的登录与注册
第一种—逻辑数据未分离
注册
- 使用注册原型的方式的axios方法进行
- 注:有后台更好
<template>
<div class="register">
<h1>注册页面</h1>
<p>用户名:<input type="text" v-model="userInfo.userid"></p>
<p>邮箱:<input type="text" v-model="userInfo.email"></p>
<p>密码:<input type="password" v-model="userInfo.userpwd"></p>
<button class="btn" @click="register()">注册</button>
</div>
</template>
<script>
// 导入qs,序列化字符串对象
import qs from 'qs';
export default {
data() {return {
userInfo : {
// 这里的数据保证跟数据接口一致
userid : '',
userpwd : '',
email : ''
}
}},
methods : {
register() {
this.$Axios.post(
"https://www.xxx.com/member/xxxxx.php",
qs.stringify(this.userInfo),
{
// 这里qs使用的stringify方法可以将对象序列化,形成json的形式进行数据获取
headers : {"content-type": "application/x-www-form-urlencoded"}
}
).then( res => {
console.log(res);
// 当获取数据的状态码等于1时,相当于获取到了
if(res.data.status == 1) {
var flag = window.confirm("确定注册码");
if(flag) {
// 跳转到登录页面
this.$router.replace("/login");
}
}
})
}
}
}
</script>
<style>
</style>
登录
- 登陆的时候使用
withCredentials : true;
传递cookie - 跨域cookie上传(服务器要求请求 localhost:8080)它指示了是否该使用类似cookies,authorization headers(头部授权)
- 或者TLS客户端证书这一类资格证书来创建一个跨站点访问控制(cross-site Access-Control)请求。
- 在同一个站点下使用withCredentials属性是无效的。
<template>
<div class="login">
<h1>登录</h1>
<p>用户名: <input type="text" v-model="user.userid"></p>
<p>密码: <input type="password" v-model="user.pwd"></p>
<p><button class="btn" @click="login()">登录</button></p>
</div>
</template>
<script>
import axios from 'axios';
import qs from 'qs';
export default{
data(){
return {user:{fmdo:"login",dopost:"login",userid:"",pwd:""}}
},
methods:{
login(){
axios.post(
"https://www.xxx.com/member/xxxx.php",
qs.stringify(this.user),
{
headers:{"Content-Type":"application/x-www-form-urlencoded"},
withCredentials:true,//跨域cookie上传(服务器要求请求 localhost:8080)
//,它指示了是否该使用类似cookies,authorization headers(头部授权)
// 或者TLS客户端证书这一类资格证书来创建一个跨站点访问控制(cross-site Access-Control)请求。
// 在同一个站点下使用withCredentials属性是无效的。
}
)
.then(res=>{
if(res.data.status == 1 ){
this.$router.replace("/user");
}
})
.catch(err=>{
console.log(err);
})
}
}
}
</script>
<style>
</style>
用户页面获取用户数据信息以及注销
<template>
<div class="user">
<div class="info">
<div class="logined" v-if="userInfo.M_ID">
<span>{{userInfo.M_UserName}}</span> |
<span>积分:{{userInfo.M_Scores}}</span> |
<span @click="loginOut()">注销</span>
</div>
<div class="nologin" v-else>
<router-link to="/login">登录</router-link>/
<router-link to="/register">注册</router-link>
</div>
</div>
</div>
</template>
<script>
export default {
data() {return {
userInfo : {}
}},
created() {
this.getUser();
},
methods : {
getUser() {
this.$Axios.get(
"https://www.xxxx.com/member/xxxx.php",
{withCredentials : true}
).then( res => {
this.userInfo = res.data;
})
},
// 注销的时间
loginOut() {
this.$Axios.post(
"https://www.xxx.com/member/xxxx.php",
"dopost=exit",
{withCredentials : true}
//
).then( res => {
if(res.data.status == 1) {
this.userInfo = {}
}
})
}
}
}
</script>
<style lang="less" scoped="scoped">
.info {
display: flex;
align-items: center;
padding: 0.3rem;
height: 1.6rem;
background-color: orange;
color: #fff;
a {
color: #fff;
}
}
</style>
第二种—逻辑数据分离—token
-
观察上一种的逻辑,发现,代码重复率很高
-
而且,如果我们需要改变一下后去数据的接口,怎么办?,难道要一个一个文件,一句一句话去更改码?
-
显然在真正的项目中,这是不现实的,所以,我们需要把数据与逻辑进行分离,
-
前端,后端,通过cookie进行数据的联系,使用token进行数据的对比校验
-
所以在这时我们需要对数据获取的axios进行封装
封装Axios
为什么封装axios?
- 实现默认配置:baseURL,timeout,headers
- 请求拦截:header添加(token,user)开启加载提示,请求数据的格式化
- 响应拦截:关闭加载提示,同意错误处理,响应数据格式
- 方法扩展:jsonp等
实现
- 在
vue-cli
中的src
文件夹下创建一个utils
目录,将封装的axios文件放在其下,命名成request.js
- 使用的有
interceptors
拦截器 - 序列化对象使用的是
qs
- 原理就是
Promise
/* 封装axios方法 */
import axios from 'axios';
import qs from 'qs';
// 导入 qs parse 方法把序列化数据转对象 stringify方法 把对象转换为 需要序列化数据 {name:"mumu",age:18}
// stringify 转序列化数据为 name=mumu&age=18
// parse把 name=mumu&age=18 转成{name:"mumu",age:18}
const BASEURL = process.env.NODE_ENV === 'production'?'https://www.xxx.com':'';
console.log(process,process.env)
// 设置基础URL (动态的根据当前的环境不一样,设置不一样的baseurl)
// process.env webpack的全局变量环境 产品|开发环境判断 给不同BASEURL
let request = axios.create({
baseURL:BASEURL,
timeout:5000
})
// 创建一个axios实例,设置实例的基础url和 超时时间
//requset.拦截器.请求.使用
request.interceptors.request.use(
config=>{
// 配置请求头的token信息,从localStorage中获取token信息,所以我们可以
// 在获取到后台数据后,将token信息放到localStorage中
config.headers.token = localStorage.getItem("token");
return config},
err=>Promise.reject(err)
)
// use 两个回调函数 ,第一个回调函数代表正确 reslove,第个回调函数错误 reject
// Promise.reject 再一次向上一一级抛出一个reject错误你
// 发送请求前个请求头headers 添加 token 头信息
// (每当是axios发起请求时候,先执行use里面回调函数方法,)
// (比如每次发起ajax请求 添加token,添加用户名 到header头信息里面)
//requset.拦截器.响应.使用
request.interceptors.response.use(
res=>{
// 写一些业务逻辑 关闭加载提示,301 404 500 等错误响应
// res.data.status ==1 ==2 ==3 响应的公共逻辑
return res;
},
err=>Promise.reject(err)
)
// 响应请求拦截
// 拦截器就是再请求前,响应前 做一些额外的公共的的事情 请求前添加loading显示 响应前 移除loading
// request是有方法 也是 对象 对象的属性是可以动态的添加(动态添加了一个方法叫postURL)
request.postURL = function(url,data,option={}){
return new Promise(function(resolve,reject){
request({
url:url,
method:"POST",
data:qs.stringify(data),
...option,
headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",...option.headers},
})
.then(res=>resolve(res))
.catch(err=>reject(err))
})
}
//添加一个 postURL方法,
// 最终返回的 当执行 postURL这个方法是最终返回的Promise对象的实例
// prosmie对象的实例 有两个结果 .then .catch(异步拿到-等待任意时间获取) 回调函数 成功
// .then 异步获取到 reslove 返回的数
// .catch 获取到 reject返回的 错误信息
/**
* jsonp 方法
* @param {tring} url 请求的地址
* @param {Object} option 参数 属性jp和属性callback jp:与后端约定回调函数名 默认值是callback | 属性callback: 回调函数名的值 默认值是jp
*
* @returns {Promise} 返回一个promise 承诺
*
* */
function jsonp(url, option = {}) {
var jp = option.jp || "callback"; //默认回调函数参数名
var callback = option.callback || "jp";//默认回调函数参数值
return new Promise((resolve, reject) => {
// 查看url是否有jp 没有还要加上
if (url.indexOf(jp) == -1) {
url += "&" + jp + "=" + callback;
}
// 获取callback的值
var p1 = url.indexOf(jp);
var p2 = url.indexOf("&", p1);
p2 == -1 ? p2 = url.length : '';
//如果查找不到设置p2位url.length;
callback = url.slice(p1 + jp.length + 1, p2);
// 动态的创建callback方法
window[callback] = function (data) {
document.head.removeChild(script);
resolve(data)
}
// 动态创建script标签
let script = document.createElement("script");
script.src = url;
document.head.append(script);
// script加载失败
script.onerror = function (e) {
document.head.removeChild(script);
reject(e)
}
})
}
// 在创建的request对象添加jsonp方法
request.jsonp = jsonp;
export default request;
// 导出 request 对象 当然就导出 request.postURL
调用封装完毕的Axios—并在添加所需要的方法
-
在
src
目录下新建一个api
文件 -
在
api
文件中定义需要在哪一个模块使用axios的文件 -
比如:我们需要登录注册,所以可以定义一个user.js文件,将所有的关于登录与注册相关的方法放入
-
具体的代码如下
import request from '@/utils/request.js';
// 登录
function Login(data){
// 返回,封装的axios中的post方法,传递获取数据的地址,以及调用这个方法是需要传递的数据
return request.postURL("/member/index_login2.php",data);
}
// 注消
function Exit(){
return request.postURL("/member/index_login2.php",{dopost:"exit"});
}
// 笑话请求
function GetJok(){
return request.postURL("/mi/list2.php");
}
// 获取用户信息
function GetUser(){
return request.get("/member/ajax_login.php")
}
// 导出,将定义的方法导出
export {
Login,
Exit,
GetJok,
GetUser
};
然后进行使用
- 使用时,只需要将已经定义的api进行调用就好
import {需要使用的方法的名字} from '地址'
登录
- 因为封装axios时,我们就已经定义了,token是从localStorage中获取的,所以在获取的时候追加
<template>
<div>
<h1>登录页面</h1>
<p><input type="text" placeholder="用户名" v-model="user.userid"></p>
<p><input type="password" placeholder="密码" v-model="user.pwd"></p>
<p><button class="btn" @click="login()">登录</button></p>
</div>
</template>
<script>
import {Login} from '@/api/user.js'
export default {
data(){
return {
user:{fmdo:"login",dopost:"login",userid:"",pwd:""},
}
},
methods:{
login(){
Login(this.user)
.then(res=>{
// 设置token 在 localstrage
if(res.data.status==1){
localStorage.setItem("token",res.data.token);
if(this.$route.query.redirect){
this.$router.replace(this.$route.query.redirect);
// 如果有redirect查询参数 跳转到对应的页面
}else{
this.$router.replace("/user");
// 默认跳转到用户中心
}
}
})
.catch(err=>console.log(err))
}
}
}
</script>
<style>
</style>
首页获取并显示用户信息及注销
- 退出时删除local Storage
<template>
<div>
<h1>个人中心</h1>
<div>
<p v-if="user.M_ID">
{{user.M_LoginID}} |
积分:{{user.M_Scores}} |
<span @click="exit()">退出</span>
</p>
<p v-else>
<router-link to="/login">登录</router-link> |
<router-link to="register">注册</router-link>
</p>
</div>
</div>
</template>
<script>
import {GetUser,Exit} from '@/api/user.js';
// 导入获取用户信息的方法 ,退出的方法
export default {
data(){return {user:{}}},
// 默认用户信息为空
created(){ this.getUser()},
// 组件创建完毕获取用户
methods:{
getUser(){
GetUser()
.then(res=>{
this.user = res.data;
})
},
// 获取用户信息
exit(){
Exit()
.then(res=>{
if(res.data.status==1){
this.user = {};
localStorage.removeItem("token");
}
})
// 退出
}
}
}
</script>
<style>
</style>
token的使用
<template>
<div>
<h1>首页</h1>
<div v-if="list.length">
<p v-for="item in list" :key="item.docid">{{item.title}}</p>
</div>
</div>
</template>
<script>
import {GetJok} from '@/api/user.js'
export default {
data(){return {list:[]}},
created(){
this.getJok();
},
methods:{
getJok(){
GetJok()
.then(res=>{
if(res.data.status==1){
alert(res.data.msg);
this.$router.push("/login?redirect=/");
// 如果权限,跳转到登录页面,给查询参数redirect为/
}
// 没有权限
if(res.data.code==0){
this.list=res.data.result;
}
// 有数据
})
}
},
}
</script>
更多推荐
已为社区贡献8条内容
所有评论(0)