在混合 App 内嵌的 h5 页面,token 失效后,提示需要重新登录,点击确定跳转至 App 的登录页面
一个很实用的场景(在手机浏览器 web 端也大同小异,原理都是一样的)
使用时失效了
拦截器统一处理,当收到 token 失效的错误码时,显示“您的账号登录已过期,或者密码已被修改,请重新登录”的弹框
http.js
http.interceptors.response.use(response => {return response;}, error => {if (error.response) {
/*
返回 3002 表示前端的 token 已失效
页面跳转到登陆页
*/
if (error.response.status == 500 && error.response.data.error == 3002) {// console.log("token 失效了");
sessionStorage.setItem("relogin", "true");
// 弹出请重新登录的弹框
Vue.prototype.$dialog({
content: "您的账号登录已过期,或者密码已被修改,请重新登录",
justAlert: true,
sureBtnText: "确定"
}).then(res => {if (res) {console.log("点击确定后执行的 app 端的回调");
}
})
}
}
return Promise.reject(error) // 返回接口返回的错误信息
});
Dialog.vue 提示组件
<template>
<div>
<a-mask v-if="settings.showMask" v-show="isShow"></a-mask>
<transition>
<div class="dialog" v-show="isShow">
<div class="dialog-title" v-if="settings.title">{{settings.title}}</div>
<div class="dialog-context">{{settings.content}}</div>
<div class="dialog-botton">
<!-- 设置只有确认按钮 -->
<span class="dialog-cancel" v-if="!settings.justAlert" @click="cancel">{{settings.cancelBtnText}}</span>
<span class="dialog-sure active" @click="sure">{{settings.sureBtnText}}</span>
</div>
</div>
</transition>
</div>
</template>
<script>
import aMask from "./Mask"
export default {
name: 'Dialog',
props: {
config: {
type: Object,
default: function() {return {};
}
}
},
data() {
return {isShow: false,}
},
computed: {
// 使用 config 传入组件配置
// settings 是将默认设置和用户设置得到的最终设置值,将默认设置与用户配置项对象合并得到
settings: function() {
return Object.assign({
showMask: true, // 是否显示蒙版
title: "", // 标题。不设置则无标题
content: "弹框内容", // 主体内容
justAlert: false, //true, 类似 aler 形式只有一个按钮,false dialog 的形式有两个按钮
cancelBtnText: "取消",
sureBtnText: "确认"
}, this.config)
}
},
components: {aMask},
methods: {show: function() {this.isShow = true;},
//close 方法只做取消当前弹窗功能
cancel: function() {
this.isShow = false;
this.$emit("close");
},
// 点击确定的时候向父组件发射事件函数
sure: function() {
this.isShow = false;
this.$emit("sure");
}
},
}
</script>
<style scoped lang="scss">
.dialog {
z-index: 6;
width: 75%;
background: rgba(255, 255, 255, 1);
position: fixed;
top: 50%;
transform: translateY(-50%);
left: 12%;
font-size: 32px;
border-radius: 25px;
}
.dialog-context{
padding: 70px 38px 52px;
text-align: center;
color: rgba(74, 74, 74, 1);
line-height: 42px;
border-bottom: 2px solid #DDDDDD;
}
.dialog-botton {
display: flex;
justify-content: space-between;
flex-direction: row;
text-align: center;
color: #3e78c4;
}
.dialog-cancel{
border-right: 2px solid #DDDDDD;
color: rgba(128, 128, 128, 1);
}
.dialog-botton span {
flex:1;
padding: 30px 0;
}
</style>
Dialog.js
import DialogView from '../../components/Dialog.vue'
// import Vue from 'vue'
let Dialog = {};
Dialog.install = function (Vue, options) {const DialogViewConstructor = Vue.extend(DialogView)
// 生成一个该子类的实例
const instance = new DialogViewConstructor();
Vue.prototype.$dialog = (config)=>{
// 这里 return 一个 Promise
// 在项目中使用的时候,就可以进行链式调用了~
return new Promise((resolve,reject)=>{
instance.config = config;
console.log(instance.config);
instance.isShow = true;
instance.sure = ()=>{
instance.isShow = false;
resolve(true)
}
instance.cancel = ()=>{
instance.isShow = false;
resolve(false)
}
})
}
// 将这个实例挂载在我创建的 div 上
// 并将此 div 加入全局挂载点内部
instance.$mount()
document.body.appendChild(instance.$el)
}
export default Dialog;
最后一定要记得在 main.js 引用
// 引入 token 提示弹框插件
import Dialog from "./modules/plugins/Dialog.js";
Vue.use(Dialog);