WeChatアプレット開発で遭遇したことのない落とし穴のまとめ

WeChatアプレット開発で遭遇したことのない落とし穴のまとめ

getApp()

getApp() 関数は、アプリ インスタンスを取得するために使用されます。通常は問題はありませんが、いくつかの特殊なシナリオでは予期しないバグが発生します。
app.js の onLaunch コールバック関数で使用

// アプリ.js
アプリ({
 起動() {
  console.info(getApp(), '!!');
 }
});

この時点では undefined が出力されているのが分かりますが、これは当然です。結局のところ、まだ初期化段階であり、アプリはまだ生まれていません。コードがそれほど単純な場合は、この問題は簡単に見つかります。コード内のメソッドを呼び出すと、このメソッドが誤ってアプリ インスタンスを取得して変数を取得すると、事故が発生します。

したがって、同期の要件がない場合は、落とし穴を回避するために、onLaunch で関数を呼び出し、setTimout でラップすることができます。

// アプリ.js
アプリ({
 起動() {
  タイムアウトを設定する(() => {
   // ... 他の関数を呼び出す });
 }
});

getApp() を変数に割り当てる

js ファイルを作成します:

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

エクスポート関数 checkVersion() {
 console.log('チェックしました!');
 console.info('アプリ', アプリ, '!!');
}

上記のファイルは通常は問題を引き起こしませんが、app.js にインポートすると、予期せぬ問題が発生します。

// アプリ.js
'a' から checkVersion をインポートします。

アプリ({
 起動() {
  console.log('私は元気です!');
 },
 オンショー() {
  バージョンチェック();
 }
});

このとき、app 変数が未定義であることがわかります。特にパッケージ化された一般的なライブラリの場合、通常は問題なく動作しますが、app.js で使用すると突然動作しなくなるため、この種のエラーを検出するのは難しい場合があります。

したがって、この問題を回避するには、パブリック アプリ インスタンスの共有を減らし、代わりにメソッド内で getApp() を直接使用してインスタンス オブジェクトを取得するようにしてください。グローバル変数を使用する場合は、変数を別の js ファイルに保存する方がよいでしょう。次に例を示します。

// グローバルストア.js

エクスポートデフォルト{
 ユーザー情報: null、
 isIos: 偽、
 isLaunched: false、
};
// アプリ.js
'globalStore' からストアをインポートします。

アプリ({
 起動() {
  ストアを起動します。
 },
 オンショー() {
  const { isLaunched } = getApp().store、
  console.log(起動済み);
 },
 店、
});

この方法では、モジュールをインポートすることでグローバル変数を取得できるほか、getApp().store を通じてグローバル変数を取得することもできます。

しかし、原則的には、モジュールをインポートしてグローバル変数を読み書きすることをお勧めします。結局のところ、getApp() は場合によっては undefined を返します。

ページエントリファイルの先頭に変数を定義します

ページ エントリ ファイルで変数を定義するのは一般的ですが、次のコードのように、ページ エントリ ファイルはページ インスタンスごとに独立して実行されるのではなく、1 回だけ実行されることに注意する必要があります。

// ページ/ページ/index.js
'api' から { getDetailInfo } をインポートします。
ajaxLock を false にします。

ページ({
 オンロード() {
  リモートデータを取得します。
 },
 非同期getRemoteData() {
  もし(ajaxロック){
   戻る;
  }
  ajaxロック = true;
  試す {
   getDetailInfo() を待機します。
  } キャッチ(エラー) {
   // ... エラーを処理する } finally {
   ajaxLock = false;
  }
 },
});

ページのロジックは比較的単純です。ページに入るとすぐにリモート データを要求します。見た目には問題ありません。ただし、複数のページを同時に開くと、最初のページだけがデータを要求し、後続のページはデータを要求しないことがわかります。これは、これらのページがすべて ajaxLock 変数を共有しているためです。したがって、ページの上部で変数を宣言する場合は、使用シナリオに注意する必要があります。

ページエントリファイルのデータにグローバル変数を直接割り当てる

コード上で直接:

// ページ/ページ/index.js
ページ({
 データ: {
  isIos: getApp().store.isIos、
 },
});

// アプリ.js
アプリ({
 起動() {
  SysInfo を取得します。
 },
 システム情報を取得する() {
  新しい Promise を返します ((resolve, reject) => {
   wx.getSystemInfoAsync({
    成功:解決、
    失敗: 拒否、
   });
  }).then((res) => {
   const { ストア } = getApp();
   store.isIos = res.platform.toLowerCase() === 'ios';
  });
 },
 店: {
  isIos: 偽、
 },
});

上記コードの主なロジックは、現在のデバイスが iOS かどうかを知ることです。シミュレーターで実行しているときはコードが非常に安定しているように見えますが、実際のマシンでは、isIos 変数が同期的にステータスを取得しないため、良い場合もあれば悪い場合もあります。ページエントリ関数の実行後に値が割り当てられると、ステータスの表示が正しくなくなります。
したがって、同期的に割り当てられない一部の状態については、初期化中にデータに直接値を割り当てないでください。onLoad コールバック関数で状態を割り当てるのが最適です。

wx.createSelectorQuery() と wx.createIntersectionObserver() について知らないこと

これら 2 つの関数もよく使用されます。wx.createSelectorQuery は主に要素を照会するために使用され、wx.createIntersectionObserver は要素が可視領域内にあるかどうかを処理するために使用されます。この2つの機能の問題点、一見かわいいものですが、特殊な要件を実装しているときに初めて発見しました。本当に後知恵で、知らないうちに強力になっていると感じていました。よく考えてみると恐ろしいですね...

問題を再現してみましょう。ページエントリ関数は次のように記述されます。

// ページ/ページ/index.js
インデックスを0にする

ページ({
 データ: {
  タグ: 0
 },
 オンロード() {
  (インデックス++ < 2)の場合{
   wx.navigateTo({
    URL: '/pages/page/index'
   });
  }
  this.setData({
   タグ: インデックス
  },() => {
   タイムアウトを設定する(() => {
    const { タグ } = this.data;
    定数クエリ = wx.createSelectorQuery();
    // 定数クエリ = this.createSelectorQuery();
    クエリを選択します(`.c-${タグ}`).boundingClientRect();
    クエリ.exec((res) => {
     console.log(タグ、res);
    });
   }, 2000);
  });
 }
});

<!-- テンプレート ファイル -->
<view class="c-{{tag}}">デモ</view>

複数のページを同時に開く状況をシミュレートしました。開発者ツールでは、最初の 2 ページの結果が null であることがわかります。 ! !その時、世界が崩壊していくように感じました。したがって、結局のところ wx.createSelectorQuery はグローバル関数なので、現在アクティブなウィンドウの下の wxml を照会するのではないかと思います。どうすれば解決できるでしょうか? 公式ドキュメントをめくって、虫眼鏡で小さな文字を探して、this.createSelectorQuery メソッドを見つけました。試してみると、突然問題が解決しました。もちろん、wx.createIntersectionObserver にも同じ問題があるので、ここでは説明しません。

したがって、健康上の理由から、this.createSelectorQuery と this.createIntersectionObserver を直接使用することを強くお勧めします。

上記は私がここ数年WeChatアプレットを開発する際に遭遇した落とし穴です。皆さんが再び陥らないことを祈ります~~

要約する

これで、WeChat ミニプログラム開発の落とし穴についての記事は終わりです。WeChat ミニプログラム開発の落とし穴の詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • taroを使用してWeChatアプレットを開発する際に遭遇する落とし穴のまとめ
  • Taro WeChatアプレット開発におけるEchartsの落とし穴
  • WeChatアプレット開発の章:落とし穴の記録

<<:  MySQL でのログインを取り消す

>>:  Filebeat を使用して Nginx ログを収集する方法

推薦する

TSオブジェクトのスプレッド演算子とレスト演算子の詳細な説明

目次概要オブジェクトの残り属性オブジェクトの拡張プロパティオブジェクトの浅いコピーを作成するkeyo...

geo モジュールを使用して Nginx でホワイトリストを設定する例

元の構成: http { ...... limit_conn_zone $binary_remote...

HTML テーブルに複雑なテーブル ヘッダーを実装するためのサンプル コード

複雑な表を作成するには HTML を使用します。複雑なテーブルでは通常、td の rowspan 属...

nginx でネストされた if メソッドを実装する方法

Nginx はネストされた if ステートメントをサポートしておらず、if ステートメントでの論理判...

CSS はスクロールバーを非表示にしてコンテンツをスクロールする効果を実現します (3 つの方法)

フロントエンド開発では、スクロールバーを非表示にしながらスクロールをサポートしなければならないという...

Zabbixは複数のmysqlプロセスの監視を実装します

1 つのサーバー上で 3 つの MySQL インスタンス プロセスが開始され、それぞれ異なるポート ...

フロントエンドアプリケーションのjenkins+gitlab+nginxデプロイメント

目次関連する依存関係のインストールドッカーDockerでJenkinsをインストールするDocker...

Tcl言語に基づくシンプルなネットワーク環境を構成するプロセスの分析

1. Tclスクリプトファイルcircle.tclコードコメント #シミュレーションに必要なプロパテ...

Linuxの運用と保守の基本プロセス管理と環境構成分析

目次1. プロセスの基本的な概要2. プロセスの構成要素3. プロセス環境4. プロセスステータス5...

新しいユーザーを作成し、MySQLに権限を付与する最も簡単な方法

ユーザーを作成します: 'oukele' によって識別されるユーザー 'ou...

CSSレイアウトにおけるフロート属性と位置属性の違い

CSS レイアウト - position プロパティposition 属性は、要素に適用する配置方法...

ubuntu20.04 上の CLion2020.1.3 での ROS のインストールと設定の詳細な説明

1. CLionをダウンロード、インストール、アクティベートするオンラインで提供されるチュートリアル...

MySQL 選択最適化ソリューションに関する簡単な説明

目次実生活からの例クエリが遅い最適化する方法カウント制限最大値と最小値 min&max実生活...

CentOS7 での MySQL 8.0.16 のインストールと設定のチュートリアル

MySQLの古いバージョンをアンインストールします(古いバージョンがない場合は、この手順をスキップし...

Vueフレームワークで習得しなければならない重要な知識を学びます

1. Vueとは何かVue は、ユーザー ページを構築するためのプログレッシブ フレームワークです。...