Vueでスケルトンスクリーンを実装する例

Vueでスケルトンスクリーンを実装する例

スケルトンスクリーンの使用

  • spa におけるルート切り替えのローディングとして、コンポーネントのライフサイクルと ajax リクエストの戻りのタイミングと組み合わせて使用​​します。(ローディングとして使用)ユーザーと最も密接な関係を持つフロントエンド開発者にとって、ユーザーエクスペリエンスは最も注意を払うべき問題です。ページの読み込み状況の表示に関しては、読み込み画像と進行状況バーの 2 つが主流です。さらに、ますます多くのアプリが「スケルトン スクリーン」方式を使用してアンロードされたコンテンツを表示し、ユーザーにまったく新しい体験を提供しています。
  • 最初の画面レンダリングの最適化として

Vueアーキテクチャスケルトンスクリーン

アイデアの概要

  • 抽象コンポーネントを定義し、抽象コンポーネントのレンダリング関数のスロットを取得します。
  • スロットを深くループし、各要素にgm-skeletonのクラス名を追加します。
  • スケルトン画面が表示されたときにデフォルトのテキストが表示されないように、事前に一時停止して vnode textContent をクリアします。
  • リターンスロット

抽象コンポーネントの定義

抽象コンポーネントとは何ですか? レンダリング中にスキップされ、実行時操作のみを実行するコンポーネントです。

    エクスポートデフォルト{
      名前: 'GmSkeleton'、
      abstract: true // 抽象コンポーネントのプロパティ}

スロットを取得し、操作スケルトン画面を初期化する

    レンダリング(h) {
      const スロット = this.$slots.default || [h('')]
      this.$nextTick().then(() => {
        this.handlerPrefix(スロット、this.showSpin ? this.addSkeletPrefix : this.removeSkeletPrefix)
      })

      スロットの長さが1より大きい場合、h('div', {
         静的クラス: this.showSpin ? 'g-spinner' : ''
      }, スロット) : スロット
    }

ここでは、handlerPrefix が実際の DOM を取得する必要があるため、スロット処理メソッドを nextTick に配置します。NextTick は、ソートされた更新キュー内のすべてのメソッドを実行するために使用されます。レンダリングを実行する前に、GMSkeleton コンポーネントの renderWatcher が更新キューに収集されています。そのため、nextTick CallBack 関数は、レンダリング後に対応するスロット内のすべての実際の DOM を取得できます。nextTick の原理がわからない場合は、nextTick についてわからないことを参照してください。

サイクルスロット操作クラス名

    handlerComponent(スロット、handler/* addSkeletPrefix | removeSkeletPrefix */、init) {
      const originchildren = (((slot.componentInstance || {})._vnode || {}).componentOptions || {}).children
      const compchildren = ((slot.componentInstance || {})._vnode || {}).children
      !init && ハンドラ(スロット)
      if (compchildren) this.handlerPrefix(compchildren, handler, false)
      if (originchildren) this.handlerPrefix(originchildren, handler, false)
    },
    handlerPrefix(スロット、ハンドラー、init = true) {
      スロット.forEach(スロット => {
        var children = slot.children || (slot.componentOptions || {}).children || ((slot.componentInstance || {})._vnode || {}).children
        if (スロットデータ) {
          スロットコンポーネントオプションの場合
            !init && ハンドラ(スロット)
          } そうでない場合 (!this.$hoc_utils.getAbstractComponent(スロット)) {
            ;(関数(スロット) {
              const handlerComponent = this.handlerComponent.bind(this, slot, handler, init)
              const 挿入 = (slot.data.hook || {}).挿入
              ;(slot.data.hook || {}).insert = () => { // 関数のリファクタリング、元のコンポーネントフックを変更し、挿入が 1 回だけ実行されるようにします insert(slot)
                ハンドラコンポーネント()
              }
              ;(slot.data.hook || {}).postpatch = handlerComponent
            }).call(this, スロット)
          }
        }
        (スロット&& slot.elm && slot.elm.nodeType === 3)の場合{
          if (this.showSpin) {
            slot.memorizedtextContent = slot.elm.textContent
            slot.elm.textContent = ''
          } それ以外 {
            slot.elm.textContent = slot.memorizedtextContent || slot.elm.textContent || slot.text
          }
        }
        children && this.handlerPrefix(children, handler, false)
      })
    },

ステップバイステップの分析:

  1. スロットを反復処理する
  2. 次のループのために現在のvnodeの下の子コレクションを取得します。
  3. ネイティブHTML要素かどうかを判断します。コンポーネントvnodeのみがcomponentOptions属性を持ちます。
  4. 抽象コンポーネントかどうかを判断します。キープアライブやトランジションなどの抽象コンポーネントは、実際のDOMTreeにレンダリングされないことがわかっています。各コンポーネントのvnodeには、init、insert、prepatch、destroyという独自のフックライフサイクルがあります。各ライフサイクルは、さまざまな段階でトリガーされます。挿入をハイジャックし、元の挿入メソッドを保持してから、vnodeの挿入メソッドを再構築して、handlerComponentメソッドを呼び出してクラス名を追加します。これは、上記のマウントされたnextTickの使用概念に似ています。handlerComponentは子コンポーネントのインスタンスを知る必要があるため、インスタンス化後に呼び出す必要があります。コンポーネントのinitメソッドは、コンポーネントをインスタンス化し、watcher.update(watcher.render())を直接呼び出します。つまり、挿入メソッドを呼び出すと、実際にはupdate(render())の後であるため、インスタンス化された子コンポーネントをここで取得できます。
  5. nodeType がテキスト ノードかどうかを判断します。テキスト ノードである場合は、textContent を保存してから削除し、スケルトン画面が表示されたときにデフォルトのテキストが表示されないようにします。スケルトン画面が消えたら、以前に保持したデフォルトのテキストを vnode に戻します。これにより、スケルトン画面の表示と非表示を自由に切り替えることができます。

vnodeを操作するための静的クラス名

    addSkeletPrefix(スロット) {
      const rootVnode = slot.componentOptions ? (slot.componentInstance || {})._vnode || {} : スロット;
      (ルートノード.elm)の場合{
        rootVnode.elm.classList.add(this.skeletPrefix)
      } それ以外 {
        ;(rootVnode.data || {}).staticClass += ` ${this.skeletPrefix}`
      }
    },
    スケルトンプレフィックスを削除します(スロット) {
      const rootVnode = slot.componentOptions ? (slot.componentInstance || {})._vnode || {} : スロット;
      (ルートノード.elm)の場合{
        rootVnode.elm.classList && rootVnode.elm.classList.remove(this.skeletPrefix)
      } そうでない場合 (rootVnode.data.staticClass) {
        rootVnode.data.staticClass = rootVnode.data.staticClass.replace(` ${this.skeletPrefix}`, '')
      }
    }

addSkeletePrefixはgm-skeletonクラス名を追加するために使用され、removeSkeletonPrefixはgm-skeletonクラス名を削除するために使用されます。

使い方

  'vue' から Vue をインポートします
  'path/to/GMSkeleton' から GMSkeleton をインポートします
  
  Vue.use(GMSkeleton)
  <gm-スケルトン>
    <コンポーネント />
    <div></div>
    <div><span>フロントエンド マーティン</span></div>
  </gm-スケルトン>

値の受け渡し

物件名価値説明する
スピンを表示ブールスケルトン画面を開くかどうか。デフォルトはtrueです。
スケルトンプレフィックススケルトンスクリーンクラス名。デフォルトは gm-skeleton です。

効果は以下のとおりです

特定のスタイルは、開発者が書いたスタイルに従って生成され、上記のようにgm-skeletonでラップされます。以下は簡単な例です。

完全な住所

Vue スケルトン スクリーンを実装するための 80 行のコード

以上がvueでスケルトン画面を実装した例の詳細です。vueでスケルトン画面を実装する方法の詳細については、123WORDPRESS.COMの他の関連記事にも注目してください!

以下もご興味があるかもしれません:
  • Vueプロジェクトのスケルトンスクリーンインジェクションの実践についての簡単な説明
  • vue-skeleton-webpack-plugin に基づくスケルトン スクリーンの練習
  • Vueモバイル端末にスケルトン画面を注入する設定方法
  • VUEシングルページアプリケーションスケルトンスクリーンソリューションの詳細な説明
  • vue-cli を使用してスケルトン スクリーンを構築する方法の例
  • Vueページのスケルトン画面の実装方法
  • Vue ページ スケルトン スクリーン インジェクション メソッド
  • Vueシングルページスケルトン画面実践記録について

<<:  MySQL 5.7.20 の解凍バージョンをインストールするための詳細な手順 (2 つの方法)

>>:  Linux で Scala 環境を構築し、簡単な Scala プログラムを書く

推薦する

例を通してMySQLの更新がテーブルをロックするかどうかを判定する

2つのケース: 1. 索引あり 2. 索引なし前提条件:方法: コマンドラインを使用してシミュレート...

HTML レイヤード ボックス シャドウ効果のサンプル コード

まず、画像を見てみましょう。今日はこのエフェクトを作成します。 実は、何でもないんです。Web ペー...

CSSで制御可能な点線を実装する方法

序文CSS を使用して点線を生成するのは、フロントエンド開発者にとっては簡単です。一般的に、これを実...

CSS3 のメディアクエリと rem レイアウトを組み合わせてモバイル画面に適応

CSS3 構文: (750 ピクセルのデザインの場合、1rem = 100 ピクセル) @media...

Dockerはローカルイメージをパッケージ化し、他のマシンに復元します

1. docker imagesを使用して、このマシン上のすべてのイメージファイルを表示します。 2...

Docker が MySQL イメージをプルするのが遅すぎる問題を解決する

Docker を使用して MySQL イメージをプルしようとして 30 分経っても失敗したため、代わ...

MySQL が innobackupex を使用して接続サーバーをバックアップできない場合の解決策

innobackupex を使用してバックアップする際に MySQL がサーバーに接続できない場合は...

centos7.2 オフラインインストール mysql5.7.18.tar.gz

ネットワークが分離されているため、MySQL は yum を使用してインストールできません。ここでは...

JS の難しさ 同期と非同期、スコープとクロージャ、プロトタイプとプロトタイプ チェーンの詳細な説明

目次JS スリーマウンテンズ同期 非同期同期と非同期の違い範囲、終了関数スコープチェーンブロックスコ...

画面なしで無線ネットワークに接続しているときに Raspberry Pi の IP アドレスを見つける方法

あなたがlinuxerだと仮定すると、 windowserだとは想定しません。Windows ユーザ...

HTML チュートリアル: よく使われる HTML タグのコレクション (6)

導入された HTML タグは、必ずしも XHTML 仕様に完全に準拠しているわけではありません。実際...

Angularが予期しない例外エラーを処理する方法の詳細な説明

前面に書かれたコードがどれだけ適切に記述されていても、すべての可能性のある例外を完全に処理することは...

WeChatアプレットがジグソーパズルゲームを実装

この記事では、WeChatアプレットでジグソーパズルゲームを実装するための具体的なコードを参考までに...

Pagoda Panel のインストール時にサーバーがデータベースにリモート接続できない問題の解決策

自分のウェブサイトを構築する予定なので、618 プロモーションを利用して Tencent Cloud...

MySQL の結合クエリとサブクエリの問題

目次複数テーブル結合の基本構文クロス結合と直積現象クロスコネクトデカルト積現象内部結合外部結合左外部...