vueページ問題の共有

9343 ワード

プロジェクト紹介
これは微信側の検索ページで、主に3つの部分を含む:検索tagページ、検索結果ページ、検索素フィルタページ.
  • 検索結果ページには、ソートフィルタ、tagサブクラスフィルタのいくつかのインタラクションがあります.
  • フィルタページインタラクション:------
  • tagページ:
  • 検索ボックス:再検索;
  • 連想語:検索ボックスの内容が変更され、関連連想語が同期的に更新される.
  • 検索履歴:前の検索レコード;
  • ホット検索語:インタフェースが返すホット検索語.


  • 問題の共有
    問題1、フィルタ弾層のスクロールスルーについて
    前期案:
    弾層をスクロールする親ボックスにスタイル{height:100%;overflow-x:hidden;overflow-y:scroll;-webkit-overflow-scrolling:touch;overflow-scrolling:touch;}を追加します.弾層の親ボックスにイベント@touchmove=「xx($event)」を追加してデフォルトのイベントをブロックします.親ボックス内のサブエレメントが下部にスクロールすると、下部の商品リストのスクロールがトリガーされます.
    問題:
  • はeventを通過する.stopPropagation(); 泡立て禁止効果がありません.
  • 行に@movestopを追加@movestopは自分でイベントをスクロールすることを禁止します---自分では動けません.

  • 後期シナリオ:
    参照iscroll:(iscroll-lite-v 5.js)
    問題1:前にスクロールボックスに設定しておいた@movestopが削除されておらず、それ自体がスライドできない.
    解決:前期設定のtouchmove関連イベントをすべて削除
    問題2:全体構成に成功した後、iscroll自体がイベントのバブル(貫通防止)を防止するために、すべてのデフォルトイベント(クリックイベントを含む)を阻止し、弾層内のすべてのクリックイベントが失効した.
    解決:iscrollを呼び出すと、一部のラベルのデフォルトイベントを解除します:preventDefaultException:{tagName:/^(INPUT|I|SPAN)$/}
    that.myScroll = new IScroll("#wrapper", {
    preventDefaultException: { tagName: /^(INPUT|I|SPAN)$/ }
    });
    

    問題3:権限を開放したラベルはクリックイベントをトリガーすることができるが、これらのラベルの上でスライドすると貫通し、下層の商品リストがスライドする.
    解決:デフォルトのイベントを開くラベルに@touchmoveを設定します.preventは、要素自体のスライドイベント(.preventはデフォルトイベントをブロック)を手動でブロックし、スライドイベントをbodyに浸すことはありません.
    {{item.name}}
    

    質問2:ページのロールバックについて
    質問背景:検索結果ページで商品をクリックし、詳細ページにジャンプし、詳細ページで戻るボタンをクリックし、さっきの検索結果ページに戻ります.製品は、以前のすべてのステータス(スクロール高さ、元のインタラクティブな痕跡)を保存する必要があります.
    :  h5       webview            ,          webview。
    

    質問:WeChatブラウザで
  • iOS携帯電話はページが戻る時、ライフサイクル中の方法(ページが更新されない)を実行せず、ページは元の状態を維持し、製品の要求に合致する.
  • アンドロイドシステムはページをリフレッシュし(jsを再実行)、元の状態はすべてリセットされます(高さは上部に戻り、操作状態はすべてクリアされます).

  • 初歩的な探索:スクロール時に現在の高さを記録し、ページのリフレッシュ時に現在の高さを読み取る.
      :         20   ,           。           ,    20    ,          ,
           dom     。          ,      20   。          ,   。(  H5         )。
    

    思考:domの高さが足りないため、対応する位置にスクロールできません.以上の方法で実現できるのは、すべてのデータが一度にロードされる(スクロールロードされない)場合のみです.しかし、これは性能を消耗しすぎます.
    発見:微信の中の京東ページは類似の問題を解決し、後退時に元の状態(すべての状態)を完璧に再現した.
    (微信--発見--買い物)
    解決:セッションストレージで現在のステータスをキャッシュします(雲見日).
  • ステップ1:ページジャンプをクリックすると、sessionStorageは、現在スクロール高さ(window.scrollTop)と各種状態(インタラクティブトレーススタイルを制御する変数)、ジャンプ前にインタフェースに要求されたすべてのデータ(商品リストのトップ画面とスクロールロードのすべての値)など、覚えておく必要がある状態値を格納します.
      :        vue   ,    ,                     ,              。     
             ,      push         (                         )。
    

  • サンプルヘッダは、商品データに値を割り当てます(対応する配列に値を割り当てます).
    if(that.resulteven.length <= that.resultodd.length){
    for (var i = 0; i < res.data.length; i++) {
    if (i % 2 == 1) {
    that.resultodd.push(res.data[i]);
    } else if (i % 2 == 0) {
    that.resulteven.push(res.data[i]);
    }
    }
    }
    

    レコードキャッシュ
    sessionVal.offsettop = $(window).scrollTop();
    sessionVal.resultodd = this.$parent.resultodd;
    sessionVal.resulteven = this.$parent.resulteven;
    sessionVal.iscur = this.$parent.iscur;    
    sessionVal.panellist = this.$parent.panellist; 
    sessionVal.maxprice = this.$parent.$refs.filterPanel.maxprice;    
    sessionVal.minprice = this.$parent.$refs.filterPanel.minprice;   
    sessionVal.filterissel = this.$parent.filterissel;         
    sessionVal.page = this.$parent.page;
    sessionVal.ajaxparameter = this.$parent.ajaxparameter;
        
    sessionStorage.setItem("sessionVal", JSON.stringify(sessionVal)); //(  sessionstorage          ,       json     )
    sessionVal = {};
    
  • ステップ2:ページリフレッシュ時にページにセッションストアがあるかどうかを判断し、ある場合は中の値を取り出して対応する変数に付与し(この場合インタフェースを要求しなくてもページをリセットせず、ジャンプ前の状態や操作痕跡を再現)、ない場合はインタフェースにページのリフレッシュを要求する.

  • キャッシュリードキャッシュがあり、なければonloadリフレッシュ
    sessionStorage.getItem("sessionVal") && (sessionVal = JSON.parse(sessionStorage.getItem("sessionVal")));
    if(!this.isIos && sessionVal){ //     ,       
    this.getSession(sessionVal);
    }else{
    this.ajax(this.ajaxparameter,'renovation');
    this.filterAjax(); //       
    this.scrollLoad(); //    
    }
    

    読み出したキャッシュは対応する割り当てを行います
    getSession:function(sessionVal){
    var that = this;
    if(sessionVal.zc){
    this.showsearchpanel = true;
    this.$refs.searchPanel.searchtext = sessionVal.searchtext;
    }
    this.resultodd = sessionVal.resultodd;
    this.resulteven = sessionVal.resulteven;
    this.iscur = sessionVal.iscur;    
    this.panellist = sessionVal.panellist ;    
    this.filterissel = sessionVal.filterissel;
    this.$refs.filterPanel.maxprice = sessionVal.maxprice;
    this.$refs.filterPanel.minprice = sessionVal.minprice;
    this.page = sessionVal.page;
    this.ajaxparameter = sessionVal.ajaxparameter;
    setTimeout(function() {
    window.scrollTo(0,sessionVal.offsettop);
    that.scrollLoad() //    
    sessionStorage.removeItem("sessionVal");
    }, 100);
    }
    

    小結
  • がキャッシュ付与方法を共通に提案したのは,この方法がその後の複数の製品が保持状態を要求する小さな問題を解決したからである.例えば、専用ページは検索ページに戻り、元の連想語(検索語を書いて検索せずにジャンプし、何を書いても何を再現し、対応する連想語を示す)
  • を機動的に保持する.
  • iosがステータスをキャッシュできる理由:back-forward cache(往復キャッシュ)
  • iosはこのbfcacheによってページ全体(domとjsを含む)をキャッシュし、退会するときにキャッシュがあれば優先的にキャッシュを読み出し、ページonloadを阻止します(キャッシュでデータを読み取るとloadはトリガーされません).ページをリフレッシュせず、キャッシュされたページを直接表示します(ネットワークの往復転送を減らし、ブラウザのスムーズさを向上させます).
  • と私たちはsessionStorageを通じてロールバックの異曲同工の効果を解決しました.それは、ページのリフレッシュを通じてそのままレンダリングしたことです(利点:ios検索ボックスのキーワードが表示されないなど、制御できないスタイルを解決することができます).
  • の異なるブラウザはbfcacheに対するサポートの程度が異なり、iosとアンドロイドは微信ブラウザのカーネルが異なり、違いをもたらした.(微信6.1以上のAndroidユーザーは、いずれもQQブラウザのX 5カーネルであり、5.4-6.1の間のバージョンであり、ユーザーAndroid QQブラウザはX 5を使用し、インストールされていない場合は自身のシステムカーネルを使用する.iOSはずっと自分のカーネルを使用しており、以前はwebkitであったが、現在はblinkカーネルに変更されている)

  • 問題3、小さな問題点のまとめ
    1.遍歴生成された複数選択枠選択クリックスタイル制御
    背景:従来、マルチ選択ボックススタイルを制御する方法は、特定のclass(addclass/removeclass)を移動することであるが、vueはdomに対する操作をできるだけ放棄し、類似の操作を継続することはできない.classは変数でしか制御できません.
    {{item.name}}
    

    質問:変数はグローバルで、1つだけです.制御が必要なclassはたくさんあります.このように変数の値を変更すると、すべてのマルチ選択ボックスが状態を変更します.しかし、複数の変数を設定して制御することはできません.
    解決:イベントをクリックして現在クリックされている要素に属性を追加し、属性値はfalseまたはtrueであり、クリック時に属性値を切り替え、この属性によって多選枠スタイルを制御する.
    現在の要素(v-forのitem)をパラメータとしてクリックイベントに渡す方法で,各要素は自身の属性値で選択するか否かを判断する.
    {{item.name}}
    

    注:Vue.set(item,'iscur',false)メソッドは、トップ要素(item)にカスタム属性を追加します.現在の要素が属性を変更していない場合にのみ設定(item.iscur==undefined)し、その属性があれば直接属性値を変更します.
    toggleClass: function(item,index){
    item.iscur == undefined ? Vue.set(item, 'iscur', false) : "";
    item.iscur = !item.iscur;
    
     :Vue.set(item, 'iscur', false)       (item)       。             
                  set( item.iscur == undefined),              ,    
          set    。
    

    2.サブコンポーネントインデックス($refs)で要素(コンポーネント)にナビゲートします(domを操作しない場合)
    質問:
    1.vueでは、以前のJQのようにidで対応する要素を直接取得することはできません.
    2.子コンポーネントは、$parentとパラメータを使用して親コンポーネントの変数とメソッドを取得できますが、平行コンポーネントと子コンポーネントのメソッドと変数をどのように取得するかは便利ではありません.
    解決:
  • サブコンポーネントまたはサブ要素内でrefでインデックスidを指定し、親コンポーネントjs内でthis.$refs.xx(ref名)サブコンポーネントに呼び出されるメソッドと変数.
  • 
    
    
    if(sessionVal.zc){
    this.showsearchpanel = true;
    this.$refs.searchPanel.searchtext = sessionVal.searchtext;
    }
    
  • サブコンポーネントとサブコンポーネントの間で、親コンポーネントをブリッジとして相手のメソッドおよび変数を呼び出すことができる.
  • sessionVal.maxprice = this.$parent.$refs.filterPanel.maxprice;    
    sessionVal.minprice = this.$parent.$refs.filterPanel.minprice;   
    sessionVal.filterissel = this.$parent.filterissel;
    

    3.微信ブラウザがページを閉じる
    背景:初めてページにアクセスし、キーワードのないデフォルトがtag検索ページにジャンプした場合、検索結果ページはキーワードがない場合、結果ページが非表示になります.検索ボックスの横にあるキャンセルボタンをクリックすると、ブラウザを直接閉じて微信チャットインタフェースに戻る必要があります.
    解決:微信内蔵機能WeixinJsBridge.call('closeWindow');
    4.autofocusへのv-if/v-showの影響について
    質問:input行にautofocusプロパティを書き込むと、domでレンダリングするときにinputがアクティブにフォーカスを取得し、ソフトキーボードがポップアップします.しかしinputの容器にv-if/v-showを設定すると異なる結果が得られる.
  • v-ifを設定するとinputボックスが現れるとソフトキーボードがポップアップします(毎回).
  • v-showを設定すると、最初に現れたときだけソフトキーボードがポップアップされ、その後隠してから現れてもポップアップされません.

  • 理由:v-ifは毎回要素を削除し、要素を追加します.毎回再レンダリングされるので、autofocusは毎回トリガーされます.v-showは最初にレンダリングされ、その後は非表示と表示(display:noneのように)され、autofocusがトリガーされたのは初めてです.
    5.thisについて異なる役割ドメインでの指代問題
    質問:プロジェクトの初期に現在のコンポーネントの変数と方法を参照する場合は、thisを直接書きます.xxx.エラーが発生し、対応する変数とメソッドが見つかりません.
    理由:メソッドには多くの異なる役割ドメインがネストされているため、thisは現在の役割ドメインのthisを指します.各メソッドの先頭にthisを変数に割り当て、その後、この変数の代わりに参照を使用して、類似の問題を解決します.
      _getSuggestion: function() {
                    var that = this; 
                    $.getJSON("http://super.fanli.com/h5/search/ajaxGetSearchWord", {keyword: this.searchtext })
                        .done(function(res) {
                            if (res.status == 1) { 
                                that.searchresult = res.data;
                            }
                        });
                },