微信小程序开发之你可能没有踩过的神坑总结

目录
  • getApp()
  • 在页面入口文件顶部定义变量
  • 你不知道的 wx.createSelectorQuery() and wx.createIntersectionObserver();
  • 总结

getApp()

getApp() 函数是用来获取 app 实例的函数,一般情况下没啥问题,但是在几个特殊的场景下它会给你带来意想不到的 bug。
在 app.js 中的 onLaunch 回调函数中使用

// app.js
App({
 onLaunch() {
  console.info(getApp(), '!!');
 }
});

你会发现这个时候会输出 undefined ,这其实可以理解,毕竟这个时候还在初始化阶段,app 还没出生。如果代码仅仅是这么简单的话,那你可以很容易的发现这个问题,一旦你在其中调用了一个方法,而这个方法又不小心在获取 app 实例来获取变量,那意外就产生了。

So~ 如果没有同步要求,可以在 onLaunch 中调用函数可以包一层 setTimout 避免踩坑:

// app.js
App({
 onLaunch() {
  setTimeout(() => {
   // ... 调用其他函数
  });
 }
});

将 getApp() 赋值给一个变量

我们创建一个 a.js 文件:

// a.js
const app = getApp();

export function checkVersion() {
 console.log('checked!');
 console.info('app', app, '!!');
}

上面的文件一般情况下不会遇到什么问题,但是一旦你在 app.js 中引入,那惊喜就产生了。

// app.js
import { checkVersion } from 'a';

App({
 onLaunch() {
  console.log('I\'m Fine!');
 },
 onShow() {
  checkVersion();
 }
});

这个时候你会发现 app 变量是 undefined,这种错误你可能很难发觉,特别是封装的一个通用库,平时好好的,但是突然在 app.js 中使用了一下,就哎嘿了。

So~ 为了避免这种问题,尽量减少公用 app 实例共享,而是在方法中直接使用 getApp() 来获取实例对象。如果要使用全局变量,可以单独一个 js 文件来单独存储变量会更好,比如:

// globalStore.js

export default {
 userInfo: null,
 isIos: false,
 isLaunched: false,
};
// app.js
import store from 'globalStore';

App({
 onLaunch() {
  store.isLaunched = true;
 },
 onShow() {
  const { isLaunched } = getApp().store,
  console.log(isLaunched);
 },
 store,
});

这样既可以通过导入模块的方式获取全局变量,又可以兼容通过 getApp().store 来获取全局变量。

但是原则上我还是建议通过导入模块的方式来读写全局变量,毕竟在某些情况下 getApp() 返回了 undefined 。

在页面入口文件顶部定义变量

在页面入口文件定义变量很常见,但是你一定要注意的是,页面的入口文件只会执行一次,并不是每个页面实例独立的,比如下面的代码:

// pages/page/index.js
import { getDetailInfo } from 'api';
let ajaxLock = false;

Page({
 onLoad() {
  this.getRemoteData();
 },
 async getRemoteData() {
  if (ajaxLock) {
   return;
  }
  ajaxLock = true;
  try {
   await getDetailInfo();
  } catch(err) {
   // ... 处理错误
  } finally {
   ajaxLock = false;
  }
 },
});

页面逻辑比较简单,一进入页面就请求远程数据,目测也没啥问题,但是一旦同时打开多个该页面,你会发现只有第一个页面请求了数据,后面的页面没有请求,因为这几个页面都共享了 ajaxLock 这个变量,因此在页面顶部声明的变量,一定要注意使用场景。

页面入口文件中 data 中直接赋值全局变量

直接上代码:

// pages/page/index.js
Page({
 data: {
  isIos: getApp().store.isIos,
 },
});
// app.js
App({
 onLaunch() {
  this.getSysInfo();
 },
 getSysInfo() {
  return new Promise((resolve, reject) => {
   wx.getSystemInfoAsync({
    success: resolve,
    fail: reject,
   });
  }).then((res) => {
   const { store } = getApp();
   store.isIos = res.platform.toLowerCase() === 'ios';
  });
 },
 store: {
  isIos: false,
 },
});

上面代码的主要逻辑就是需要知道当前设备是不是 ios ,代码在模拟器上跑着似乎很稳定,但是一旦上了真机,就时好时坏了,因为 isIos 这个变量不是同步获取状态的,一旦赋值在页面入口函数执行完之后,那么状态的展现就会不正确。
因此对于某些状态不是同步赋值,千万不要直接通过在初始化的时候直接给 data 赋值的方式去操作,最好放到 onLoad 回调函数中去赋值状态。

你不知道的 wx.createSelectorQuery() and wx.createIntersectionObserver();

这两个函数也是比较常用的,wx.createSelectorQuery 主要用来查询某个元素,wx.createIntersectionObserver 用在需要处理元素是否在可视区。这两个函数的问题目测纯纯的可爱,我也是在实现某个特殊需求的时候才发现,也真是后知后觉,不明觉厉,细思极恐...

我们来复现问题,页面入口函数这么写:

// pages/page/index.js
let index = 0

Page({
 data: {
  tag: 0
 },
 onLoad() {
  if (index++ < 2) {
   wx.navigateTo({
    url: '/pages/page/index'
   });
  }
  this.setData({
   tag: index
  },() => {
   setTimeout(() => {
    const { tag } = this.data;
    const query = wx.createSelectorQuery();
    // const query = this.createSelectorQuery();
    query.select(`.c-${ tag }`).boundingClientRect();
    query.exec((res) => {
     console.log(tag, res);
    });
   }, 2000);
  });
 }
});
<!-- 模板文件 -->
<view class="c-{{tag}}">demo</view>

我模拟了同时打开多个页面的情况,在开发者工具中你就会发现,前两个页面的结果居然是 null !!!当时我就觉得世界有点儿崩塌。因此我怀疑毕竟 wx.createSelectorQuery 是一个全局函数,因此它查询的是当前活跃窗口下的 wxml。怎么解决呢,我翻了翻官方文档,用放大镜找了找小字,发现有 this.createSelectorQuery 这个方法,抱着试一试的态度,问题就突然解决了。当然 wx.createIntersectionObserver 也是同样的问题,我就不做演示了。

So~ 为了身体好,我强烈建议直接使用 this.createSelectorQuery 和 this.createIntersectionObserver 。

以上是我这几年开发微信小程序踩过的神坑,望你不要再踩上~~

总结

到此这篇关于微信小程序开发之你可能没有踩过的坑的文章就介绍到这了,更多相关微信小程序开发的坑内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 微信小程序开发篇之踩坑记录

    最近参与开发了公司的第一款小程序,开发体验基本类似于基于webview的混合式开发,可以调用官方强大的api,但也有一些坑或者说不习惯的地方.这篇文章从实用性出发,记录了开发过程中的一些问题: 1. 样式优先级混乱 在使用button组件时,发现在class中设置width不生效,下面贴上代码: .my-button{ width: 140rpx; height: 60rpx; line-height: 60rpx; padding: 0; } 经过微信调试工具排查后,发现user agent的

  • Echarts在Taro微信小程序开发中的踩坑记录

    背景 近期笔者在使用Taro进行微信小程序开发,当引入Echarts图表库时,微信检测单包超限2M的一系列优化措施的踩坑记录,期望能指导读者少走一些弯路. 为什么选择Echarts? 微信小程序目录市面上使用最多的两款图表库,如下: echarts-for-weixin--echarts微信小程序版本 wx-charts--基于微信小程序的图表库 对比两款图表库优缺点刚好相反. echarts-for-weixin:功能强大,但体积非常大 wx-charts:功能相对简单,但体积小 由于笔者对e

  • 使用taro开发微信小程序遇到的坑总结

    Taro,京东凹凸实验室出品的适配多端的一个框架,Taro 是一套遵循 React 语法规范的 多端开发 解决方案.现如今市面上端的形态多种多样,Web.React-Native.微信小程序等各种端大行其道,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要. 一.taro开发搭建 1.taro很方便就在于其环境搭建很轻松,照着官方文档几行代码就能搭建好. 2.在进行预览的时候,不同的方式区别是很大的

  • 微信小程序开发之你可能没有踩过的神坑总结

    目录 getApp() 在页面入口文件顶部定义变量 你不知道的 wx.createSelectorQuery() and wx.createIntersectionObserver(); 总结 getApp() getApp() 函数是用来获取 app 实例的函数,一般情况下没啥问题,但是在几个特殊的场景下它会给你带来意想不到的 bug. 在 app.js 中的 onLaunch 回调函数中使用 // app.js App({ onLaunch() { console.info(getApp()

  • 微信 小程序开发环境搭建详细介绍

    微信小程序可谓是今天最火的一个名词了,一经出现真是轰炸了整个开发人员,当然很多App开发人员有了一个担心,微信小程序的到来会不会给移动端App带来一个寒冬,身为一个Android开发者我是不相信的,即使有,那也是很遥远的未来. 不管微信小程序是否能颠覆当今的开发格局,我们都要以好奇的心态去接收,去学习.不排斥新技术,所以,心动不如行动,赶紧先搭建一个微信小程序开发工具.那么接下来就让我们一起来开始吧. 先放一张Github上demo的动态图 开发工具下载是看到GitHub上的分享.那么你可以直接

  • 微信小程序开发之选项卡(窗口底部TabBar)页面切换

    微信小程序开发中窗口底部tab栏切换页面很简单很方便. 代码: 1.app.json //app.json { "pages":[ "pages/index/index", "pages/logs/logs" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": &qu

  • 微信小程序开发图片拖拽实例详解

    微信小程序开发图片拖拽实例详解 1.编写页面结构:moveimg.wxml <view class="container"> <view class="cnt"> <image class="image-style" src="../uploads/foods.jpg" style="left:{{ballleft}}px;width:{{screenWidth}}px" bi

  • 微信小程序开发之实现选项卡(窗口顶部TabBar)页面切换

    微信小程序开发中选项卡.在Android中选项卡一般用fragment,到了小程序这里瞬间懵逼了. 总算做出来了.分享出来看看. 先看效果: 再上代码: 1.index.wxml <!--index.wxml--> <view class="swiper-tab"> <view class="swiper-tab-list {{currentTab==0 ? 'on' : ''}}" data-current="0"

  • 微信小程序开发入门基础教程

    微信小程序开发入门基础教程 本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果. 开发准备工作获取微信小程序的 AppID 登录 https://mp.weixin.qq.com ,就可以在网站的"设置"-"开发者设置"中,查看到微信小程序的 AppID 了,注意不可直接使用服务号或订阅号的 AppID . 下载开发工具 下载地址:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/dow

  • Android中微信小程序开发之弹出菜单

    先给大家展示下效果图,具体效果图如下所示: 具体代码如下所示: 1.index.js //index.js //获取应用实例 var app = getApp() Page({ data: { isPopping: false,//是否已经弹出 animationPlus: {},//旋转动画 animationcollect: {},//item位移,透明度 animationTranspond: {},//item位移,透明度 animationInput: {},//item位移,透明度

  • 微信小程序开发之好友列表字母列表跳转对应位置

    微信小程序开发之好友列表字母列表跳转对应位置 前言: 在小程序里实现微信好友列表点击右侧字母列表跳转对应位置效果.写了个demo,核心部分很简单,所以没多少注释,如果遇到问题就加群问我吧. 核心技术点: 1.小程序scroll-view组件的scroll-into-view, scroll-with-animation. scroll-y属性. 2.小程序的touch事件的应用. 3.Js定时器的应用. view页面代码: index.wxml class="container" sc

  • 微信小程序开发实战教程之手势解锁

    代码:https://github.com/jsongo/wx-gesture-lock 这个手势解锁的demo使用了https://github.com/lvming6816077/H5lock这个项目的算法和主逻辑,整合到微信小程序来,修改了很多地方的语法来适配小程序,去掉了window.document等函数,同时也添加了新的机制来解耦界面的操作和第三方库,这个下面会介绍到. 不过可惜的是,这个demo也只能在开发工具上玩玩,到真机上测试的时候,手指一滑动,页面会跟着滚动,手势没法使用.

  • 微信小程序 开发指南详解

    编写代码 创建小程序实例 点击开发者工具左侧导航的"编辑",我们可以看到这个项目,已经初始化并包含了一些简单的代码文件.最关键也是必不可少的,是 app.js.app.json.app.wxss 这三个.其中,.js后缀的是脚本文件,.json后缀的文件是配置文件,.wxss后缀的是样式表文件.微信小程序会读取这些文件,并生成小程序实例. 下面我们简单了解这三个文件的功能,方便修改以及从头开发自己的微信小程序. ​ app.js是小程序的脚本代码.我们可以在这个文件中监听并处理小程序的

随机推荐