文章目录

  • 前言
  • 一、Page页面扩展
    • 1.组件的封装和引用
    • 2.页面使用
    • 3.效果
  • 二、其他相关封装
    • 1.pop-up组件
    • 2.LoginPanel组件
    • 3.LoginPanel组件

前言

在小程序日常开发中,有些功能是所有页面都需要使用的,所以就需要对每个page页面进行扩展,在小程序中Page 的作用相当于构造函数, Page 会初始化页面对象然后将配置参数中的属性 merge 到页面对象上。

一、Page页面扩展

1.组件的封装和引用

extend-page.js


const extendPage = Page => {return object => {// 登录面板开头if (!object.data) object.data = {}object.data.showLoginPanel = false // methodobject.hi = function(name){console.log(`hi ${name}`);}// 派发一个等待处理,需要有代码处理的事件// 但这个方法没有什么用object.triggerWaitingEvent = function (type, data = {}){return new Promise((resolve,reject)=>{let eventCallback = res => resolve(res)Object.assign(data, {eventCallback})this.triggerEvent(type, data)})}return Page(object)}
}const originalPage = Page
Page = extendPage(originalPage)

app.js中引入扩展页面

require("./lib/extend-page")

2.页面使用

<button bindtap="extendPage" type="primary">请求</button>
<LoginPanel show="{{showLoginPanel}}"></LoginPanel>
  async extendPageTest(){this.hi('weapp')// 使用request3let res4 = await wx.wxp.request4({url: 'http://localhost:3000/user/home',})if (res4) console.log('res4', res4)},

3.效果

二、其他相关封装

1.pop-up组件


Component({options: {multipleSlots: true // 在组件定义时的选项中启用多slot支持},/*** 组件的属性列表*/properties: {visible: {type: Boolean,value: false}},/*** 组件的初始数据*/data: {},ready(){this.triggerEvent('ready')},/*** 组件的方法列表*/methods: {popPreventTouchmove() { },popPreventTouchmove2() { },popPreventTouchmove3() { },cityChange() { },close() {this.triggerEvent('close')},handleClickMask(e) {// console.log(e)if (e.target.dataset.type !== 'unclose') this.close()}}
})
<view catchtouchmove="popPreventTouchmove"><view class="q-pp-mask  {{ visible ? 'q-pp-mask-show' : '' }} ptp_exposure" bindtap="handleClickMask" catchtouchmove="popPreventTouchmove"><view class=" q-pp {{ visible ? 'q-pp-show' : '' }}" catchtouchmove="popPreventTouchmove"><slot name="content" data-type="unclose"></slot></view></view>
</view>
.q-pp {position: fixed;width: 100%;box-sizing: border-box;left: 0;right: 0;bottom: 0;background: #f7f7f7;transform: translate3d(0, 100%, 0);transform-origin: center;transition: all 0.2s ease-in-out;z-index: 900;visibility: hidden;
}.q-pp-show {transform: translate3d(0, 0, 0);visibility: visible;
}.q-pp-mask {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0, 0, 0, 0.7);z-index: 900;transition: all 0.2s ease-in-out;opacity: 0;visibility: hidden;
}.q-pp-mask-show {opacity: 1;visibility: visible;
}

2.LoginPanel组件

<pop-up visible="{{visible}}"><view slot="content"><view class="picker-view"><view class="picker-view__pane"><text bindtap="close">取消</text></view><view style="font-size:17px;font-weight:bold;line-height:30px;border-bottom:1px solid #f2f2f2;padding: 0px 0 20px;width: 100%;color:#353535;text-align: center;">微信授权登录</view><image style="width: 40px;height: 40px;padding-top: 20px;" src="../../components/custom-tab-bar/component-on.png"></image><view style="font-size:17px;font-weight:400;color:#353535;line-height: 40px;">小程序将申请获取以下权限</view><view style="font-size:11px;color:#b2b2b2;border-bottom:1px solid #f2f2f2;width: 100%;padding: 0px 0 40px;text-align: center;">● 获得你的公开信息(昵称、头像、地区及性别)</view><view style="height:80px;padding-top: 20px;"><button bindgetuserinfo="login" open-type="getUserInfo" type="primary">登陆</button></view></view></view>
</pop-up>

.picker-view {width: 100%;display: flex;background-color: #fff;flex-direction: column;justify-content: center;align-items: center;bottom: 0rpx;left: 0rpx;
}.picker-item {line-height: 70rpx;margin-left: 5rpx;margin-right: 5rpx;text-align: center;
}.picker-view__pane {height: 100rpx;width: 100%;padding: 20rpx 32rpx;display: flex;justify-content: space-between;align-items: center;box-sizing: border-box;
}.picker-view__pane text{color: #00cc88;font-size: 30rpx;
}.pick-view__group {width: 96%;height: 450rpx;
}
Component({options: {multipleSlots: false},properties: {show: {type: Boolean,value: false}},observers: {'show': function (value) {console.log(value);this.setData({visible: value})}},data: {visible: false},ready() {},methods: {close(e) {this.setData({visible: false})},async login(e, retryNum = 0) {let {userInfo,encryptedData,iv} = e.detail// 本地token与微信服务器上的session要分别对待let tokenIsValid = false, sessionIsValid = falselet res0 = await getApp().wxp.checkSession().catch(err=>{// 清理登陆状态,会触发该错误// checkSession:fail 系统错误,错误码:-13001,session time out…d reloginconsole.log("err",err);tokenIsValid = false})console.log("res0", res0);if (res0 && res0.errMsg === "checkSession:ok") sessionIsValid = truelet token = wx.getStorageSync('token')if (token) tokenIsValid = trueif (!tokenIsValid || !sessionIsValid) {let res1 = await getApp().wxp.login()let code = res1.codeconsole.log("code",code);let res = await getApp().wxp.request({url: 'http://localhost:3000/user/wexin-login2',method: 'POST',header: {'content-type': 'application/json','Authorization': `Bearer ${token || ''}`},data: {code,userInfo,encryptedData,iv,sessionKeyIsValid:sessionIsValid}})if (res.statusCode == 500){if (retryNum < 3){this.login.apply(this, [e, ++retryNum])}else{wx.showModal({title: '登录失败',content: '请退出小程序,清空记录并重试',})}return}// Error: Illegal Buffer at WXBizDataCrypt.decryptDataconsole.log('登录接口请求成功', res.data)token = res.data.data.authorizationTokenwx.setStorageSync('token', token)console.log('authorization', token)}getApp().globalData.token = tokenwx.showToast({title: '登陆成功了',})this.close()this.triggerEvent('loginSuccess')getApp().globalEvent.emit('loginSuccess')},login2(e) {let {userInfo,encryptedData,iv} = e.detail// console.log('userInfo', userInfo);const requestLoginApi = (code) => {//发起网络请求wx.request({url: 'http://localhost:3000/user/wexin-login2',method: 'POST',header: {'content-type': 'application/json'},data: {code: code,userInfo,encryptedData,iv},success(res) {console.log('请求成功', res.data)let token = res.data.data.authorizationTokenwx.setStorageSync('token', token)onUserLogin(token)console.log('authorization', token)},fail(err) {console.log('请求异常', err)}})}const onUserLogin = (token) => {getApp().globalData.token = tokenwx.showToast({title: '登陆成功了',})this.close()this.triggerEvent('loginSuccess')getApp().globalEvent.emit('loginSuccess')}const login = () => {wx.login({success(res0) {if (res0.code) {requestLoginApi(res0.code)} else {console.log('登录失败!' + res0.errMsg)}}})}wx.checkSession({success() {//session_key 未过期,并且在本生命周期一直有效console.log('在登陆中');let token = wx.getStorageSync('token')if (token) {onUserLogin(token)} else {// session会重复,需要处理login()}},fail() {// session_key 已经失效,需要重新执行登录流程login()}})}}
})
{"component": true,"usingComponents": {"pop-up": "../pop-up/index"}
}

3.LoginPanel组件

//app.js
require("./lib/extend-page")
// import Event from './lib/event'
import Event from './lib/event2'
import wxp from './lib/wxp'// getApp().globalEvent
App({wxp: (wx.wxp = wxp),globalData: (wx.globalData = {}),globalEvent: (wx.globalEvent = new Event()),onLaunch: async function () {if (!wx.cloud) {console.error('请使用 2.2.3 或以上的基础库以使用云能力')} else {wx.cloud.init({// env 参数说明://   env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源//   此处请填入环境 ID, 环境 ID 可打开云控制台查看//   如不填则使用默认环境(第一个创建的环境)env: 'default-98491d',traceUser: true,})}this.globalData = {}},
import {promisifyAll
} from 'miniprogram-api-promise';const wxp = {}
promisifyAll(wx, wxp)// compatible usage
// wxp.getSystemInfo({success(res) {console.log(res)}})wxp.request2 = function (args) {let token = wx.getStorageSync('token')if (token) {if (!args.header) args.header = {}args.header['Authorization'] = `Bearer ${token}`}return wxp.request(args).catch(function (reason) {console.log('reason', reason)})
}//
wxp.request3 = function(args){let token = wx.getStorageSync('token')if (!token){return new Promise((resolve, reject)=>{let pageStack = getCurrentPages()if (pageStack && pageStack.length > 0) {let currentPage = pageStack[pageStack.length-1]currentPage.setData({showLoginPanel2:true})getApp().globalEvent.once("loginSuccess", ()=>{wxp.request2(args).then(res=>{resolve(res)}, err=>{console.log('err', err);reject(err)})})}else{reject('page valid err')}})}return wxp.request2(args)
}wxp.request4 = function (args) {let token = wx.getStorageSync('token')if (!token) {let pages = getCurrentPages()let currentPage = pages[pages.length - 1]// 展示登陆浮窗currentPage.setData({showLoginPanel: true})return new Promise((resolve, reject) => {getApp().globalEvent.once('loginSuccess', function (e) {wxp.request2(args).then(function (result) {resolve(result)}).catch(function (reason) {console.log('reason', reason);})})})}return wxp.request2(args).catch(function (reason) {console.log('reason', reason);})
}export default wxp

【愚公系列】2022年09月 微信小程序-Page页面扩展相关推荐

  1. 【愚公系列】2022年09月 微信小程序-微信小程序实现网页一键登录功能

    文章目录 前言 一.微信小程序实现网页一键登录功能 1.旧版登录方法 2.新版登录方法 二.相关第三方包源码 前言 如果微信小程序要获取微信登录的用户信息,需要拿到code去后台换取用户信息,具体步骤 ...

  2. 【愚公系列】2022年09月 微信小程序-webview内嵌网页的授权认证

    文章目录 前言 一.webview内嵌网页的授权认证 1.内嵌页面 2.登录页面 二.web端相关函数 1.判断是否是小程序环境 前言 随着微信小程序的广泛应用,小程序的用户越来越多,但受其小程序体积 ...

  3. 【愚公系列】2022年09月 微信小程序-图片加载和全屏适配问题

    文章目录 前言 一.图片加载 二.适配机型实现全屏背景图 前言 在使用图片问题中可能会遇到各种各样的问题,比如图片加载不出来,图片显示在不同机型效果不同,图片加载展示问题等等. 微信小程序image相 ...

  4. 【愚公系列】2022年09月 微信小程序-自定义导航栏功能的实现

    文章目录 前言 一.自定义导航栏功能的实现 1.组件的封装 2.使用 前言 导航栏是指位于页面顶部或者侧边区域的,在页眉横幅图片上边或下边的一排水平导航按钮,它起着链接站点或者软件内的各个页面的作用. ...

  5. 【愚公系列】2022年09月 微信小程序-图片懒加载功能实现

    文章目录 前言 一.官方图片的懒加载 1.wxml 2.js 3.css 4.效果 二.第三方包实现图片的懒加载 1.安装第三方包 2.组件引用 3.wxml 4.js 5.css 6.效果 前言 大 ...

  6. 【愚公系列】2022年09月 微信小程序-WebGL立体图形的绘制

    文章目录 前言 一.webgl的使用 1.立体图形的绘制 二.相关包源码 三.总结 前言 WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaS ...

  7. 【愚公系列】2022年09月 微信小程序-WebGL纹理材质的使用

    文章目录 前言 一.webgl的使用 1.立体图形的绘制 二.相关包源码 三.总结 前言 WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaS ...

  8. 【愚公系列】2022年09月 微信小程序-three.js绘制正方体

    文章目录 前言 一.Three.js的使用 1.正方体的绘制 二.正方体相关js文件 三.效果图 四.总结 前言 Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括 ...

  9. 【愚公系列】2022年09月 微信小程序-WebGL画渐变色正方形

    文章目录 前言 一.webgl的使用 1.画正方形 二.相关包源码 三.总结 前言 WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScri ...

最新文章

  1. 一些零碎知识(域名、DNS、浏览器、动态静态页面、web应用系统工作原理)
  2. 什么是好的图神经网络?
  3. 最新《医学图像深度语义分割》综述论文
  4. DXperience_v9.15简体中文
  5. 如何让所请读取的数据自动产生编号.
  6. Search Engine —— Regular Expression(Spider)
  7. 工程用计算机是什么样子的,【2人回答】学软件工程的应该买什么样的处理器电脑?-3D溜溜网...
  8. Python 39 数据库的数据类型
  9. datatable排序:DataTable的排序、检索、合并
  10. sql 语句循环方法的使用
  11. 中铁置业引入USB Server助力RPA机器人
  12. 优秀的项目经理应该具备的能力
  13. 转变为灰度图像的算法优化及马赛克实现代码
  14. 常用的vim命令,主要是写给宝贝儿方便工作查看的
  15. 尚硅谷nginx学习
  16. 推荐几个ai生成绘画软件给你
  17. 批量转换 LF 和 CRLF 的小技巧【详细步骤】
  18. 11. python入门复习教程之命名空间与作用域,再谈异常,标准库,持久化与序列化
  19. cad在线转成低版本的途径分享,适合新手
  20. 深圳市万泰达科技发展有限公司人员需求信息:外贸销售/亚马逊/Amazon

热门文章

  1. upc-WNJXYK and DIDIDI and monkey(并查集启发式合并)
  2. 腕表珠宝成为女性跨境消费新晋宠儿;爱彼迎全球约55%的新增房东为女性 | 美通企业日报...
  3. 新媒体学院运营模式提要-V1
  4. laydate实现日期多选
  5. 泰克福禄克安捷伦吉时利数字万用表软件二次开发NS-Multimeter
  6. 为战疫助力,半导体功不可没
  7. 953-验证外星语词典
  8. 关于OPC UA TSN中TSN
  9. Linux C语言中的read write lseek的使用
  10. ATA标准规范文件说明及下载