現状WeChat ミニプログラムには、ホームページ、個人ページ、いくつかのリストページ、詳細ページなどがあり、これらのページのほとんどは共有できます。共有ページが別のユーザーによって開かれた場合、そのページはどのようにしてそのユーザーがログインしていることを確認できますか? インターネット上には、リクエストのカプセル化にインターセプションを追加するソリューションが多数あります。トークンがない場合は、続行する前にログイン リクエストを呼び出してトークンを取得します。 このソリューションに問題はありません。ただ、1 点だけ注意してください。ページが複数のリクエストによって同時にトリガーされると、すべてのリクエストがインターセプトされた後、それらは配列に配置されます。トークンを正常に取得した後、配列を反復処理して 1 つずつリクエストします。 しかし、コンビニチェーンのアプリのように要件がもう少し複雑な場合は、ほとんどのページにストアが必要です(ストアに基づいて現在の店舗の商品の在庫や価格などを取得する必要があるため)。このストアは、現在の場所に基づいてバックエンドインターフェースを呼び出すことで取得されます。このとき、リクエストにカプセル化するのは面倒すぎます。 解決まず、ログイン、位置情報の取得、ページ リクエストが非同期であることに気付きました。ページ リクエストがログインと位置情報の取得の後に行われるようにする必要がありますが、ページごとに記述すると保守性が悪くなります。したがって、これを行うためのメソッドを抽出できます。 コードは次のようになります: const アプリ = getApp() ページ({ データ: { ログ: [] }, オンロード() { app.commonLogin(()=>{ // ページリクエストを処理する }) } }) ここで問題は解決したように思えますが、もう一度考えてみましょう。各ページの onShareAppMessage の処理を統一するなど、さらにやりたいことがありますが、ページごとに再度記述したくないので、各ページのウォッチを自分で実装したい場合は、どうすればよいでしょうか。 さらなる解決策WeChat アプレットでは、各ページが Page() であることがわかります。そのため、このページの外側にシェルを追加し、このページを置き換える MyPage を作成できます。さっそく、コードを示します。 tool.js 関連コード /** * プロセスマージパラメータ */ handlePageParamMerge(引数) { let numargs = arg.length; // 渡されたパラメータの値を取得します。 データを {} とします ページを{}にします (引数にixを入れる) { アイテム = arg[ix]とする if (item.data && typeof (item.data) === 'object') { データ = Object.assign(データ、アイテム.データ) } if (item.methods && typeof (item.methods) === 'object') { ページ = Object.assign(ページ、アイテム.メソッド) } それ以外 { ページ = Object.assign(ページ、アイテム) } } page.data = データ 戻るページ } /*** * ページメソッドとデータをマージします。{data:{}、methods:{}} または {data:{}、a:{}、b:{}} と互換性があります。 */ マージページ() { this.handlePageParamMerge(引数) を返します。 } /** * コンポーネントパラメータのマージ処理 */ ハンドルCompParamMerge(引数) { let numargs = arg.length; // 渡されたパラメータの値を取得します。 データを {} とします オプションを {} にします プロパティを {} にします メソッドを {} にします comp = {} とします。 (引数にixを入れる) { アイテム = arg[ix]とする // コンポーネントの初期データをマージします if (item.data && typeof (item.data) === 'object') { データ = Object.assign(データ、アイテム.データ) } // コンポーネントのプロパティリストをマージします if (item.properties && typeof (item.properties) === 'object') { プロパティ = Object.assign(プロパティ、item.properties) } // 結合されたコンポーネントのメソッドのリスト if (item.methods && typeof (item.methods) === 'object') { メソッド = Object.assign(メソッド、item.methods) } if (item.options && typeof (item.options) === 'object') { オプション = Object.assign(オプション、item.オプション) } comp = Object.assign(comp, アイテム) } comp.data = データ comp.options = オプション comp.properties = プロパティ comp.methods = メソッド 返品コンプ } /** * コンポーネント ミックスイン {プロパティ: {}、オプション: {}、データ:{}、メソッド: {}} */ マージコンポーネント() { this.handleCompParamMerge(引数) を返します。 } /*** * ウォッチでページを合成 */ 新しいページ() { オプション = this.handlePageParamMerge(引数) それを = これとする アプリを getApp() にします //グローバルクリックログイン判定を追加 if (!options.publicCheckLogin){ options.publicCheckLogin = 関数 (e) { ページを getCurrentPages() にします ページ = pages[pages.length - 1]とします。 データセット = e.currentTarget.dataset とします コールバックを null にする //コールバックメソッドを取得する if (dataset.callback && typeof (page[dataset.callback]) === "function"){ コールバック = ページ[データセット.コールバック] } // console.log('コールバック>>', コールバック, app.isRegister()) //ログインするかどうかを判定する if (callback && app.isRegister()){ コールバック(e) } それ以外{ wx.navigateTo({ url: '/pages/login/login' }) } } } const { onLoad } = オプション options.onLoad = 関数 (引数) { options.watch && that.setWatcher(this) onLoad && onLoad.call(this, arg) } const { onShow } = オプション options.onShow = 関数 (引数) { if (options.data.noAutoLogin || app.isRegister()) { onShow && onShow.call(this, arg) //ページ埋め込み app.ga({}) } それ以外 { wx.navigateTo({ url: '/pages/login/login' }) } } ページに戻る(オプション) } /** * 時計などでコンポーネントを合成します */ 新しいコンポーネント() { オプション = this.handleCompParamMerge(引数) それを = これとする const { ready } = オプション options.ready = 関数 (引数) { options.watch && that.setWatcher(this) 準備完了 && ready.call(this, arg) } コンポーネント(オプション)を返す } /** * リスナーを設定する */ setWatcher(ページ) { data = page.data; とします。 watch = page.watch; とします。 Object.keys(watch).forEach(v => { let key = v.split('.'); // ウォッチ内の属性を '.' の配列に分割します。let nowData = data; // nowData にデータを割り当てます。 for (let i = 0; i < key.length - 1; i++) { // 最後の要素を除く、キー配列の要素を走査します。 nowData = nowData[key[i]]; // nowDataをそのキー属性オブジェクトにポイントします} lastKey = key[key.length - 1]とします。 // key==='my.name'、nowData===data['my']===data.my、lastKey==='name' と仮定します。 let watchFun = watch[v].handler || watch[v]; // ハンドラの有無にかかわらず互換性あり let deep = watch[v].deep; // deepが設定されていない場合は未定義です this.observe(nowData, lastKey, watchFun, deep, page); //nowDataオブジェクトのlastKeyを監視する }) } /** * 属性を監視し、監視機能を実行する */ 観察(obj, キー, watchFun, ディープ, ページ) { var val = obj[キー]; // deep が true であり、val が空でないこと、typeof val==='object' であることを確認します (配列内の値の変更にも deep 監視が必要です) if (deep && val != null && typeof val === 'object') { Object.keys(val).forEach(childKey => { // valオブジェクトの下の各キーを走査します this.observe(val, childKey, watchFun, deep, page); // 監視関数を再帰的に呼び出す}) } var that = this; Object.defineProperty(obj, キー, { 設定可能: true、 列挙可能: true、 設定: 関数 (値) { if (val === 値) { 戻る } // ページ オブジェクトを呼び出し、関数内の this ポインターを変更して、this.data がデータ内のプロパティ値にアクセスできるようにします。watchFun.call(page, value, val); // value は新しい値、val は古い値です。val = value; if (deep) { // ディープモニタリングの場合は、オブジェクトのプロパティを監視するためにオブジェクトを再度リッスンします。 that.observe(obj、key、watchFun、deep、page); } }, 取得: 関数 () { 戻り値: } }) } ページコード: app.tool.newPage({ データ: { // 自動ログインなし: false }, onShow: 関数() { //ここにページリクエストロジックを記述します} } やっとこのコードは長い間オンラインで実行されています。ツール内の newPage パッケージは、必要に応じて追加できます。つまり、ここでは考え方を 1 つ紹介しているだけです。もっと良い考え方があれば、ぜひ共有してください。 これで、WeChat ミニプログラムがどのようにしてすべてのページのログインを確実にするかについてのこの記事は終了です。WeChat ミニプログラムがどのようにしてページのログインを確実にするかについての関連コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
SASS を使用する開発者が増えるにつれて、SASS コードの数に注意する必要があります。 SASS...
1. はじめにフロントエンドページのアニメーション効果を記述する場合、filter 属性は多かれ少な...
【1】<i></i>タグと<em></em>タグ同じ...
1. 結論構文: 制限オフセット、行結論: 同じ行条件では、オフセット値が大きいほど、limitステ...
MySQL が複数のテーブルを結合するときに、次のエラーが報告されます: [Err]1267 – 操...
シェルスクリプトを使用したMySQLデータベースの自動バックアップデータベースを頻繁にバックアップす...
序文一部の CSS 相互作用の影響により、要素に設定されたz-index実際のサイズに応じて重ね合わ...
目次問題の概要問題の再現問題の拡大結論は問題の概要今日、仕事中に、DBA が突然、SQL に暗黙的な...
Mysqlが2つのテーブルを関連付けると、次のエラーメッセージが生成されます:照合順序の不正な組み合...
目次1. エラー現象2. エラー分析3. エラー解決1. エラー現象仮想マシンでLVGLエミュレータ...
目次1. 場所オブジェクト1. URL 2. 場所オブジェクトのプロパティ3. ロケーションオブジェ...
MySQL サーバーをシャットダウンする場合、シャットダウン方法に応じてさまざまな問題が発生する可能...
VMware12.0+Ubuntu16.04+MySQL5.7.22 インストールチュートリアルの詳...
この例で使用されているMySQLのバージョンはmysql-8.0.15-winx64です。 1. z...
目次1. クライアントとサーバー間の通信方法2. クエリキャッシュ3. クエリ最適化処理4. クエリ...