小程序的页面劫持是在网上偶尔知道的方法,感觉很流氓(但是我喜欢)。原理就是利用了对象的原型继承,在页面开始前做些自己需要的更改。
来看这个案例:
根据产品的要求,需要把小程序很多页面做成入口页,每个入口页都需要做授权验证操作。
(一开始我提出可以做出一个单独验证登录页面,所有分享页面都是这个页面,然后在根据传的参数分发到各个不同的页面,但是这个方案被否了,说是影响用户体验);那就只能在当前页面弹框。
方案一:每个页面都复制一份代码;这个方案直接就被我否掉了。
方案二:写成组件,每个页面引入组件。 这个方案的可行性可以说是很高的。
方案三:用模板加上页面劫持。(这个方案可以使公共模板和页面的联系紧密)。
相对于方案二,由于我的项目需要抽出的公共模块和页面联系紧密,所以我选择用了方案三。
下面我就来个阉割版编写过程:
- 新建小程序项目 hijackPage;
- 把该清理的多余东西都删除掉,留下一片干净的地方让我们开始涂鸦;
- 新建一个页面,我们要测试用,就叫做userInfo;
- 在根目录创建一个(template)文件夹用来存放我们的模板文件。
- 新建一个模板文件夹(login)。文件夹有login.wxss;login.wxml文件。
- 在utils文件夹(公共js文件夹)新建一个hijack_login.js文件;这个就是我们劫持页面用的文件。
- 在要用模板的页面引入模板,并且把页面劫持。
现在就来看看代码:
template.wxml写一个弹框用户授权:
<template name="login"> // name 表示模板名字,在页面引入的时候用
<view class='{{showImpowerTip ? "login_box" : "hide"}}'>
<view class='login_content'>
<view class='login_c_tip'>提示</view>
<view class='login_c_txt'>你还没有授权登录哦,赶紧授权登录,就可以体验小程序啦!!</view>
<view class='login_c_click'>
<text class='login_c_btn color_999 click' catchtap='hideshowImpowerTip'>放弃</text>
<text class='login_c_btn_fg'></text>
<button class='login_c_btn color_1aad19 click' open-type="getUserInfo" bindgetuserinfo="getUser">授权</button>
</view>
</view>
</view>
</template>
Template.wxss:
.hide {
display: none;
}
.login_box {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.4);
display: flex;
align-items: center;
justify-content: center;
}
.login_content {
width: 500rpx;
background-color: #fff;
box-sizing: border-box;
padding-top: 30rpx;
}
.login_c_tip {
font-size: 30rpx;
color: #333;
text-align: center;
}
.login_c_txt {
margin-top: 20rpx;
font-size: 26rpx;
color: #666;
text-align: center;
line-height: 44rpx;
padding: 0 40rpx;
}
.login_c_click {
display: flex;
flex-direction: row;
margin-top: 30rpx;
border-top: 2rpx solid #d7d7d7;
}
.login_c_btn {
flex: 1;
border: none;
background-color: #fff;
text-align: center;
padding: 0;
margin: 0;
height: 88rpx;
line-height: 88rpx;
font-size: 30rpx;
border-radius: 0;
}
.login_c_btn_fg {
display: inline-block;
width: 2rpx;
height: 88rpx;
background-color: #d7d7d7;
}
.login_c_btn::after {
border: none;
}
.color_1aad19{
color: #1aad19;
}
.color_999{
color: #999999;
}
.click:active {
background-color: rgba(0, 0, 0, 0.2);
}
hijack_login.js:
function hijackPage(obj) {
obj.data.showImpowerTip = false; // 是否显示用户授权提示框
obj.data.userMsg = null; // 用户信息对象
if(obj.onLoad) {
var _onLoad = obj.onLoad;
obj.onLoad = function(opt) {
this.judgeImpower();
_onLoad.apply(this, [opt]);
}
}
obj.judgeImpower = function() { // 判断用户是否授权
var that = this;
wx.getSetting({
success(res){
if(res.authSetting["scope.userInfo"]) {
that.setData({
showImpowerTip: false
})
if (!that.data.userMsg) {
wx.getUserInfo({
success: user=> {
that.setData({
userMsg: user.userInfo
})
}
})
}
}else {
that.setData({
showImpowerTip: true
})
}
}
})
}
obj.getUser = function(e) { // 获取用户信息
console.log(e);
if(e.detail.userInfo) {
this.setData({
userMsg: e.detail.userInfo
})
this.judgeImpower();
}else {
this.hideshowImpowerTip();
}
}
obj.hideshowImpowerTip= function() {
this.setData({
showImpowerTip: false
})
}
Page(obj); // 执行
}
module.exports={
hijackPage,
}
页面中引入模板:
Index.wxml:
<view class=''>
<view class='user_box'>
<image class='user_img' src='{{userMsg.avatarUrl ? userMsg.avatarUrl : ""}}'></image>
<view class='user_name'>
<text class='{{userMsg.nickName ? "user_title" : "hide"}}'>{{userMsg.nickName ? userMsg.nickName : ""}}</text>
<button class='{{userMsg.nickName ? "hide" : "user_title"}}' open-type="getUserInfo" bindgetuserinfo="getUser">点击授权登录</button>
</view>
</view>
<view class='go_user_c'>
<text class='go_user_btn' catchtap='goUserInfo'>个人中心</text>
</view>
</view>
<import src="/template/login/login.wxml" /> <!-- 引入模板 -->
<template is="login" data="{{showImpowerTip}}" />
hijack_login.js引入页面实现劫持:
index.js:
//index.js
//获取应用实例
var Page = require("../../utils/hiijack_login.js").hijackPage; // 引入劫持页面
const app = getApp()
Page({
data: {
},
onLoad: function () {
},
goUserInfo: function() { // 跳转到个人中心页
wx.redirectTo({
url: '/pages/userInfo/userInfo',
})
}
})
个人中心页面也同样的方法引入。(后面所有新加的页面,只要需要这样操作的,就这样引入就行了)。
那么我们就实现进入页面的时候判断是否授权,如果没有授权,那么弹框提示授权,取消授权以后,去到其他页面一样会提示授权。