微信小程序常用简易小函数总结


Posted in Javascript onFebruary 01, 2019

本文实例讲述了微信小程序常用简易小函数。分享给大家供大家参考,具体如下:

最近一直在写微信小程序,而且由于是第二次写了,所以针对很多通用的情况封装了一些函数,建议你们放在app.js中,方便全局去调用。

提示类函数

微信有一种原生的API用于显示提示类结果的wx.showToast,而且其中的图片是可以自定义的,所以为了保证全部一致性,而且方便调用,所以我将其全部封装在了app.js中:

// 成功
showSuccess: function (message) {
    wx.showToast({
      title: message,
      duration: 2000,
      image: "/images/Common/Success.png",
    })
  },
// 错误
showError: function (message) {
    wx.showToast({
      title: message,
      duration: 2000,
      image: "/images/Common/Error.png",
    })
  },
// 警告
showWarn: function (message) {
    wx.showToast({
      title: message,
      duration: 2000,
      image: "/images/Common/Warn.png",
    })
  }

注意上面的duration参数,这个在下面的情况中是一个很重要的问题。

假设一般的操作是对一个页面的操作完成后接着显示处理结果,最后进行跳转。所以这里就存在一个问题,假设使用上面的弹出框进行显示,那么在弹出框显示之前就会进行跳转,这样处理结果就显示不全了,所以合理的做法是在弹出框结束后进行跳转。而如果将跳转单独封装在各个页面中,那么到时候进行时间长短的处理就很麻烦了,所以我将这个函数进行了封装:

// 第一个是路由,第二个则是判断是否是tabbar的路由,跳这两个路由是不一致的
completeOperating:function(to,isTabbar){
    var time=setTimeout(function(){
      if(isTabbar===true){
        wx.switchTab({
          url:to
        })
      }else{
        wx.navigateTo({
         url: to
        })
      }
      clearTimeout(time);
    },2000)
}

还有一种情况就是我们开始将数据返回给后端,这个时候最好给用户一个加载中的提示,而这个提示可以使用wx.showLoadding来做:

// 提示用户数据保存中
startOperating:function(info){
    wx.showLoading({
      title:info,
      mask:true
    })
  }

当后端返回结果后。则将加载框进行隐藏:

stopOperating:function(){
    wx.hideLoading();
  }

登录类问题

微信小程序不支持session,这个是前提,所以我们没办法在后端使用session来进行用户身份的区分。我的解决思路是这样的,在项目的入口文件app.js中的onLaunch函数中,即在用户开启小程序后调用wx.login()函数获取用户的唯一微信标志code,接着将该标志传回后端,调用微信的统一API,获取用户在该微信小程序中的唯一标识,注意,即使是同一个用户,在不同的微信小程序中标识也是不一样的。

获取该标识后,后端调用缓存将该标识缓存起来,时间也不用担心,由于写在app.js中,所以每次启动都会去询问后端,后端做相应的登录更新处理就可以了。

实际前端代码

// app.js
APP({
 onLaunch:function(){
  this.login();
 },
 login:function(){
  // 我喜欢把域名保存在globalData中,这样即使后期修改了域名,也不用到每个文件中去改
  var that=this;
  wx.login({
   success:function(res){
    // 这里获取标识
    var code=res.code;
    // 将该标识传递给后端
    wx.request({
     url:that.globalData.url+"/home/login/login?code="+code,
     success:function(res){
      // 假设后端返回一个session_key作为改用户的唯一标识,所有请求都需要携带该参数
      var session_key=res.data.session_key;
      // 调用全局缓存来保存该值
      wx.setStorageSync('session_key', session_key);
     },
     fail:function(error){
      // 写这么一个函数,是帮助自己后期出现问题时可以进行修复
      console.error("调用微信登录接口错误");
      console.log(error);
     }
    })
   }
  })
 },
 globalData:{
  url:"http://yourdomain.com"
 }
})

实际后端代码

class LoginController extends Controller{
 // 你的小程序唯一标识
 private $appid="";
 private $secrect="";
 public function login(){
  // 获取前端传递过来的code
  $code=$_GET['code'];
  // 调用微信的统一API
  $baseUrl="https://api.weixin.qq.com/sns/jscode2session?appid={$this->appid}&secret={$this->secrect}&js_code={$code}&grant_type=authorization_code";
  // 微信返回结果处理
  $result=curl_get_contents($baseUrl);
  $user=json_decode($result,true);
  if($user['error_code']){
   // 这里是调用错误的函数,如何解决看你自己的业务逻辑
   exit();
  }
  // 该用户在你小程序中的唯一标识
  $openid=$user['openid'];
  // 判断是新用户还是老用户
  $userInfo=M('User')->where(array('openid'=>$openid))->find();
  if($userInfo){
   // 老用户
   $user_id=$userInfo['id'];
   $session_key=$this->getSessionKey($openid,$user_id);
  }else{
   // 新用户则将其保存进数据库中
   $user_id=M("User")->add(array('openid'=>$openid));
   $session_key=$this->getSessionKey($openid,$user_id);
  }
  // 缓存起来,至于有效期最好长一点,以防止用户在使用过程中突然不能访问数据,我这里是使用tp框架的S()函数进行存储的
  S($session_key,$user_id);
  // 以后只需要用户传递过来$session_key就可以根据缓存获取用户身份了
  // 将结果发送给前端
  $this->ajaxReturn(array(
    'session_key'=>$session_key
  ));
 }
 // 生成用户的session_key
 private function getSessionKey($openid,$user_id){
  $key="可以说是你的密钥吧";
  return hash("md5",$key.$openid.$user_id);
 }
}

当然这里我只是保存了$user_id,如果你需要更多信息可以考虑使用redis,memcached等进行长期缓存,反正每次产生的$session_key都是一样的。

Session_key使用例子

上面我们获取了session_key并在前后端进行了保存,接下来就是如何使用该session_key了。

后端验证

关于CommonContrller的原理请看之前的一篇博客:tp框架的RBAC实现

class CommonController extends Controller{
 protected $user_id;
 public function ___initialize(){
  // 对用户的session_key进行验证
  $session_key=I("session_key");
  $user_id=S($session_key);
  if(!$user_id){
   // 该$session_key失效或者不合法
   $this->ajaxReturn(array('result'=>"请退出小程序重新登录"));exit();
  }
  $this->user_id=$user_id;
 }
}

接着假设下面是你真正想要访问的方法

class IndexController extends CommonController{
 public function(){
  // 假设这里你需要获取当前用户的id,只需要直接调用父类中的属性就可以了
  $user_id=$this->user_id;
 }
}

上面我们就借用了我们生成的session_key配合上缓存模拟了session的验证机制,希望对你们有用。

前端实现

getData:function(){
 // 从缓存中获取session_key,并将其传递给后端,做用户身份的确认
 var session_key=wx.getStorageSync('session_key');
 wx.request({
  url:app.globalData.url+"/home/index/index?session_key="+session_key,
  success:function(res){
   //
  }
 })
}

前置页面做优化

上面我们是在app.js的onLaunch中直接调用登录函数,但是这样却存在一个问题,那就是登录没有完成,就跳转到入口的page中,接着由于session_key还没有生成,导致页面数据请求失败。我当时就是遇到了这个问题,所以我把入口的page设置成了前置页面,并在前置页面中添加了下面的函数:

onLoad: function (options) {
    var time=setInterval(function(){
      var session_key=wx.getStorageSync('session_key');
      // 只有当session_key存在时,才跳转到首页去,保证请求数据的有效性,否则就在前置页面暂留一会
      if(session_key.length>5){
        wx.switchTab({
          url:"/pages/index/index"
        })
        clearInterval(time);
      }
    },1000);
}

希望本文所述对大家微信小程序开发有所帮助。

Javascript 相关文章推荐
js的闭包的一个示例说明
Nov 18 Javascript
JavaScript 学习笔记之数据类型
Jan 14 Javascript
JS实现跟随鼠标闪烁转动色块的方法
Feb 26 Javascript
jQuery添加和删除输入文本框标签代码
May 20 Javascript
AngularJS入门教程之ng-class 指令用法
Aug 01 Javascript
javascript 秒表计时器实现代码
Mar 09 Javascript
vue loadmore组件上拉加载更多功能示例代码
Jul 19 Javascript
import与export在node.js中的使用详解
Sep 28 Javascript
Vue全局loading及错误提示的思路与实现
Aug 09 Javascript
vue-socket.io接收不到数据问题的解决方法
May 13 Javascript
vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip
Jun 02 Javascript
在vue项目中利用popstate处理页面返回的操作介绍
Aug 06 Javascript
使用Angular自定义字段校验指令的方法示例
Feb 01 #Javascript
angular中如何绑定iframe中src的方法
Feb 01 #Javascript
Javascript迭代、递推、穷举、递归常用算法实例讲解
Feb 01 #Javascript
JS集合set类的实现与使用方法示例
Feb 01 #Javascript
详解如何使用webpack打包多页jquery项目
Feb 01 #jQuery
详解Vue中watch对象内属性的方法
Feb 01 #Javascript
JS字典Dictionary类定义与用法示例
Feb 01 #Javascript
You might like
PHP简单系统数据添加以及数据删除模块源文件下载
2008/06/07 PHP
PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别
2014/11/20 PHP
php post json参数的传递和接收处理方法
2018/05/31 PHP
如何在PHP中使用数组
2020/06/09 PHP
关于viewport,Ext.panel和Ext.form.panel的关系
2009/05/07 Javascript
前端微信支付js代码
2016/07/25 Javascript
jQuery实现Select左右复制移动内容
2016/08/05 Javascript
js图片轮播手动切换特效
2017/01/12 Javascript
动态统计当前输入内容的字节、字符数的实例详解
2017/10/27 Javascript
在React 组件中使用Echarts的示例代码
2017/11/08 Javascript
基于jQuery实现定位导航位置效果
2017/11/15 jQuery
浅析vue深复制
2018/01/29 Javascript
vue异步加载高德地图的实现
2018/06/19 Javascript
layui表单提交到后台自动封装到实体类的方法
2019/09/12 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
2019/09/19 Javascript
Node.js中文件系统fs模块的使用及常用接口
2020/03/06 Javascript
Nodejs 数组的队列以及forEach的应用详解
2021/02/25 NodeJs
Python引用(import)文件夹下的py文件的方法
2014/08/26 Python
python中Flask框架简单入门实例
2015/03/21 Python
Python入门之三角函数atan2()函数详解
2017/11/08 Python
Python进阶学习之特殊方法实例详析
2017/12/01 Python
python excel使用xlutils类库实现追加写功能的方法
2018/05/02 Python
python处理multipart/form-data的请求方法
2018/12/26 Python
Artist Guitars新西兰:乐器在线商店
2017/09/17 全球购物
廉价航班、机票和酒店:JustFly
2018/02/07 全球购物
面向对象编程OOP的优点
2013/01/22 面试题
十八大闭幕感言
2014/01/22 职场文书
幼儿园大班开学教师寄语
2014/04/03 职场文书
同居协议书范本
2014/04/23 职场文书
优秀教导主任事迹材料
2014/05/09 职场文书
护士医德医风自我评价
2014/09/15 职场文书
房屋转让协议书
2014/10/18 职场文书
教师个人工作总结范文2014
2014/11/10 职场文书
大学生求职意向书
2015/05/11 职场文书
Vue.js中v-bind指令的用法介绍
2022/03/13 Vue.js
HTML常用标签超详细整理
2022/03/19 HTML / CSS