vue-router からのフロントエンドルーティングの 2 つの実装

vue-router からのフロントエンドルーティングの 2 つの実装

フロントエンド アプリケーションのビジネス機能がますます複雑になり、ユーザー エクスペリエンスに対するユーザーの要件がますます高くなるにつれて、シングル ページ アプリケーション (SPA) がフロントエンド アプリケーションの主流の形式になりました。大規模なシングルページ アプリケーションの最も注目すべき機能の 1 つは、ページを再要求せずに URL を変更することでページ ビューを更新するフロントエンド ルーティング システムの使用です。

「ページを再リクエストせずにビューを更新する」ことは、フロントエンド ルーティングのコア原則の 1 つです。現在、ブラウザ環境でこの機能を実装するには、主に次の 2 つの方法があります。

  • URLのハッシュ(「#」)を悪用する
  • 履歴インターフェースを使用した HTML5 の新しいメソッド

vue-router は、Vue.js フレームワークのルーティング プラグインです。まずはソース コードから始めて、コードと原理を読み、vue-router がこれら 2 つの方法を通じてフロントエンド ルーティングを実装する方法を浅いところから深いところまで学んでいきましょう。

モードパラメータ

vue-router では、mode パラメータを使用してルーティング実装モードを制御します。

const ルーター = 新しい VueRouter({
  モード: '履歴'、
  ルート: [...]
})

VueRouter のインスタンス オブジェクトを作成するときに、モードがコンストラクター パラメーターとして渡されます。疑問を念頭に置きながらソースコードを読んでいくと、VueRouter クラスの定義から始めることができます。通常、プラグインによって公開されるクラスは、ソースコード src のルート ディレクトリにある index.js ファイルで定義されます。ファイルを開くと、VueRouter クラスの定義を確認できます。mode パラメータに関連する抜粋は次のとおりです。

デフォルトクラスVueRouterをエクスポートします。
  
  mode: string; // 渡された文字列パラメータは履歴カテゴリを示しますhistory: HashHistory | HTML5History | AbstractHistory; // 実際に機能するオブジェクトプロパティは、上記の 3 つのクラスの列挙である必要がありますfallback: boolean; // ブラウザがサポートしていない場合は、「履歴」モードを「ハッシュ」モードにロールバックする必要がありますconstructor (options: RouterOptions = {}) {
    
    let mode = options.mode || 'hash' // デフォルトは 'hash' モードです this.fallback = mode === 'history' && !supportsPushState // supportsPushState を使用して、ブラウザーが 'history' モードをサポートしているかどうかを判断します if (this.fallback) {
      モード = 'ハッシュ'
    }
    ブラウザ内で
      mode = 'abstract' // ブラウザ環境で実行されていない場合は、強制的に 'abstract' モードにします}
    this.mode = モード

    // モードに基づいて実際の履歴クラスを決定し、switch (mode) をインスタンス化します。
      ケース「履歴」:
        this.history = 新しい HTML5History(this、options.base)
        壊す
      ケース 'ハッシュ':
        this.history = 新しい HashHistory(this、options.base、this.fallback)
        壊す
      ケース「抽象」:
        this.history = 新しい AbstractHistory(this、options.base)
        壊す
      デフォルト:
        process.env.NODE_ENV !== 'production' の場合 {
          assert(false, `無効なモード: ${mode}`)
        }
    }
  }

  init (app: any /* Vueコンポーネントインスタンス */) {
    
    定数履歴 = this.history

    // 履歴カテゴリに応じて対応する初期化操作と監視を実行します。if (history instanceof HTML5History) {
      history.transitionTo(history.getCurrentLocation())
    } そうでない場合 (history instanceof HashHistory) {
      const セットアップハッシュリスナー = () => {
        履歴.setupListeners()
      }
      履歴の遷移先(
        履歴.getCurrentLocation()、
        セットアップハッシュリスナー、
        セットアップハッシュリスナー
      )
    }

    history.listen(ルート => {
      this.apps.forEach((アプリ) => {
        app._route = ルート
      })
    })
  }

  // VueRouter クラスによって公開される次のメソッドは、実際には特定の履歴オブジェクトのメソッドを呼び出します push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
    this.history.push(場所、onComplete、onAbort)
  }

  置換 (場所: RawLocation、onComplete?: Function、onAbort?: Function) {
    this.history.replace(場所、onComplete、onAbort)
  }
}

次のことがわかります。

パラメータとして渡される文字列属性モードは、実際に動作するオブジェクト属性履歴の実装クラスを示すための単なるマーカーです。両者の対応関係は次のとおりです。

モード歴史ハッシュ抽象的な
歴史HTML5の歴史ハッシュ履歴概要歴史

対応する履歴を初期化する前に、モードのチェックが行われます。ブラウザが HTML5History メソッドをサポートしていない場合 (supportsPushState 変数によって判断)、モードは強制的に 'hash' に設定されます。ブラウザ環境で実行されていない場合、モードは強制的に 'abstract' に設定されます。

VueRouter クラスの onReady()、push() などのメソッドは単なるプロキシです。実際には、特定の履歴オブジェクトの対応するメソッドを呼び出します。init() メソッドで初期化されると、履歴オブジェクトの特定のカテゴリに応じて異なる操作が実行されます。

ブラウザ環境の 2 つのメソッドは、それぞれ HTML5History クラスと HashHistory クラスに実装されています。これらはすべて src/history フォルダーに定義されており、同じディレクトリ内の base.js ファイルで定義されている History クラスから継承されます。 History は一般的な基本メソッドを定義しますが、直接読むと混乱する可能性があります。まずは、HTML5History クラスと HashHistory クラスのよく知られた push() メソッドと replace() メソッドから始めましょう。

ハッシュ履歴

ソースコードを見る前に原則を確認しましょう。

ハッシュ ("#") 記号は、もともと Web ページの場所を示すために URL に追加されます。

https://www.example.com/index.html#… を参照してください。

# 記号自体とそれに続く文字はハッシュと呼ばれ、window.location.hash プロパティを通じて読み取ることができます。以下の機能があります:

  • ハッシュは URL に表示されますが、HTTP リクエストには含まれません。これはブラウザの動作をガイドするために使用され、サーバーにはまったく役に立ちません。したがって、ハッシュを変更してもページはリロードされません。
  • ハッシュの変更に対するリスナー イベントを追加できます。
window.addEventListener("hashchange", funcRef, false)

ハッシュ (window.location.hash) が変更されるたびに、ブラウザのアクセス履歴に記録が追加されます。

ハッシュの上記特性を利用することで、フロントエンドルーティングにおいて「ビューを更新するがページを再リクエストしない」という機能を実装することができます。

ハッシュ履歴.push()

HashHistory の push() メソッドを見てみましょう。

プッシュ (場所: RawLocation、onComplete?: Function、onAbort?: Function) {
  this.transitionTo(場所、ルート => {
    pushHash(ルート.fullPath)
    onComplete && onComplete(ルート)
  }, 中止時)
}

関数pushHash(パス){
  window.location.hash = パス
}

transitionTo() メソッドは、ルート変更の基本ロジックを処理するために親クラスで定義されています。push() メソッドは主に、ウィンドウのハッシュを直接割り当てるために使用されます。

window.location.hash = ルート.fullPath

ハッシュの変更はブラウザのアクセス履歴に自動的に追加されます。

では、ビューはどのように更新されるのでしょうか? 親クラス History の transitionTo() メソッドを見てみましょう。

transitionTo (場所: RawLocation、onComplete?: Function、onAbort?: Function) {
  const ルート = this.router.match(場所、this.current)
  this.confirmTransition(ルート、() => {
    this.updateRoute(ルート)
    ...
  })
}

updateRoute (ルート: ルート) {
  
  this.cb && this.cb(ルート)
  
}

listen (cb: 関数) {
  this.cb = cb
}

ご覧のとおり、ルートが変更されると、History の this.cb メソッドが呼び出され、History.listen(cb) を通じて this.cb メソッドが設定されます。 VueRouter クラスの定義に戻ると、init() メソッドで設定されていることがわかりました。

init (app: any /* Vueコンポーネントインスタンス */) {
    
  this.apps.push(アプリ)

  history.listen(ルート => {
    this.apps.forEach((アプリ) => {
      app._route = ルート
    })
  })
}

コメントによると、app は Vue コンポーネント インスタンスですが、プログレッシブ フロントエンド フレームワークである Vue は、コンポーネント定義に組み込みルート属性 _route を持つべきではないことがわかっています。コンポーネントにこの属性が必要な場合は、プラグインがロードされる場所、つまり VueRouter の install() メソッドで、Vue オブジェクトにミックスする必要があります。install.js ソース コードを確認すると、次の段落があります。

エクスポート関数インストール (Vue) {
  
  Vue.mixin({
    作成前() {
      if (isDef(this.$options.router)) {
        this._router = this.$options.router
        this._router.init(これ)
        Vue.util.defineReactive(this, '_route', this._router.history.current)
      }
      インスタンスを登録します(これ、これ)
    },
  })
}

Vue.mixin() メソッドを通じて、ミックスインはグローバルに登録され、登録後に作成されるすべての Vue インスタンスに影響します。ミックスインは、beforeCreate フックの Vue.util.defineReactive() を通じて、レスポンシブな _route 属性を定義します。いわゆる responsive プロパティは、_route 値が変更されると、Vue インスタンスの render() メソッドが自動的に呼び出され、ビューが更新されることを意味します。

まとめると、ルート変更の設定からビューの更新までのプロセスは次のようになります。

$router.push() --> HashHistory.push() --> History.transitionTo() --> History.updateRoute() --> {app._route = route} --> vm.render()

ハッシュ履歴.replace()

replace() メソッドは、新しいルートをブラウザのアクセス履歴スタックの先頭に追加するのではなく、現在のルートを置き換えるという点で push() メソッドとは異なります。

置換 (場所: RawLocation、onComplete?: Function、onAbort?: Function) {
  this.transitionTo(場所、ルート => {
    ハッシュを置換(ルート.fullPath)
    onComplete && onComplete(ルート)
  }, 中止時)
}
  
関数 replaceHash (パス) {
  定数 i = window.location.href.indexOf('#')
  ウィンドウの場所を置き換える(
    window.location.href.slice(0, i >= 0 ? i : 0) + '#' + パス
  )
}

実装構造は基本的にpush()と似ていることがわかります。違いは、window.location.hashに直接値を割り当てるのではなく、window.location.replaceメソッドを呼び出してルートを置き換えることです。

アドレスバーを聞く

上で説明した VueRouter.push() と VueRouter.replace() は、vue コンポーネントのロジック コード内で直接呼び出すことができます。また、ブラウザでは、ユーザーがブラウザのアドレス バーにルートの変更を直接入力することもできます。そのため、VueRouter はブラウザのアドレス バーでルートの変更を監視し、コードを介して呼び出す場合と同じ応答動作を実現できる必要があります。 HashHistory では、この関数は setupListeners を通じて実装されます。

セットアップリスナー() {
  window.addEventListener('ハッシュ変更', () => {
    if (!ensureSlash()) {
      戻る
    }
    this.transitionTo(getHash(), ルート => {
      ハッシュを置換(ルート.fullPath)
    })
  })
}

このメソッドは、ブラウザ イベント hashchange をリスナーとして設定し、呼び出される関数は replaceHash です。つまり、ブラウザのアドレス バーにルートを直接入力することは、コード内で replace() メソッドを呼び出すことと同じです。

HTML5の歴史

履歴インターフェースは、ブラウザの履歴スタックによって提供されるインターフェースです。back()、forward()、go() などのメソッドを通じて、ブラウザの履歴スタックの情報を読み取り、さまざまなジャンプ操作を実行できます。

HTML5 以降、History インターフェースには pushState() と replaceState() という 2 つの新しいメソッドが用意されており、ブラウザの履歴スタックを変更できるようになります。

window.history.pushState(状態オブジェクト、タイトル、URL)
window.history.replaceState(状態オブジェクト、タイトル、URL)
  • stateObject: ブラウザが新しい状態にジャンプすると、popStateイベントがトリガーされ、このstateObjectパラメータのコピーが渡されます。
  • title: 追加するレコードのタイトル
  • URL: 追加するレコードのURL

これら 2 つのメソッドには共通の機能があります。ブラウザの履歴スタックを変更するために呼び出されると、現在の URL が変更されても、ブラウザは URL にすぐにリクエストを送信しません (ブラウザは pushState() の呼び出し後にこの URL の読み込みを試行しません)。これにより、シングル ページ アプリケーションのフロントエンド ルーティングが「ビューを更新するがページを再リクエストしない」という基礎が提供されます。

vue-router のソースコードを見てみましょう。

プッシュ (場所: RawLocation、onComplete?: Function、onAbort?: Function) {
  const { current: fromRoute } = this
  this.transitionTo(場所、ルート => {
    pushState(cleanPath(this.base + route.fullPath))
    handleScroll(this.router, ルート, fromRoute, false)
    onComplete && onComplete(ルート)
  }, 中止時)
}

置換 (場所: RawLocation、onComplete?: Function、onAbort?: Function) {
  const { current: fromRoute } = this
  this.transitionTo(場所、ルート => {
    replaceState(cleanPath(this.base + route.fullPath))
    handleScroll(this.router, ルート, fromRoute, false)
    onComplete && onComplete(ルート)
  }, 中止時)
}

// src/util/push-state.js
エクスポート関数pushState(url?:文字列、replace?:ブール値){
  スクロール位置を保存します。
  // Safari を回避するために pushState 呼び出しをキャッチしてみてください
  // DOM 例外 18 では、pushState 呼び出しが 100 回に制限されます
  定数履歴 = window.history
  試す {
    (置換)の場合{
      history.replaceState({ キー: _key }, '', url)
    } それ以外 {
      _key = genKey()
      history.pushState({ キー: _key }, '', url)
    }
  } キャッチ (e) {
    window.location[replace ? 'replace' : 'assign'](url)
  }
}

エクスポート関数replaceState(url?: string) {
  プッシュステート(url, true)
}

ビューを更新するコード構造とロジックは基本的にハッシュ モードと同様ですが、window.location.hash を window.location.replace() に直接割り当てる代わりに、history.pushState() メソッドと history.replaceState() メソッドを呼び出すように変更されています。

HTML5History のブラウザ アドレス バーの URL を変更するためのリスナーを追加すると、コンストラクター内で直接実行されます。

コンストラクタ (ルータ: Router、ベース: ?string) {
  
  window.addEventListener('popstate', e => {
    定数 current = this.current
    this.transitionTo(getLocation(this.base)、ルート => {
      if (expectScroll) {
        handleScroll(ルーター、ルート、現在、true)
      }
    })
  })
}

もちろん、HTML5History は HTML5 の新機能を使用するため、特定のブラウザ バージョンのサポートが必要です。すでに説明したように、ブラウザがサポートしているかどうかは、変数 supportsPushState を通じてチェックされます。

// src/util/push-state.js
エクスポートconst supportsPushState = inBrowser && (function () {
  定数 ua = window.navigator.userAgent

  もし (
    (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
    ua.indexOf('モバイルSafari') !== -1 &&
    ua.indexOf('Chrome') === -1 &&
    ua.indexOf('Windows Phone') === -1
  ){
    偽を返す
  }

  window.history && 'pushState' を window.history で返す
})()

以上がハッシュモードと履歴モードのソースコードの紹介です。両モードともブラウザインターフェースを通じて実装されています。また、vue-router はブラウザ以外の環境向けに抽象モードも用意しています。原理は配列スタックを使用してブラウザ履歴スタックの機能をシミュレートすることです。もちろん、上記はコアロジックの一部にすぎません。システムの堅牢性を確保するために、ソースコードには多くの補助ロジックがあり、それらも学習する価値があります。さらに、vue-routerにはルートマッチングやルータービューのビューコンポーネントなどの重要な部分があります。

2つのモードの比較

一般的な需要シナリオでは、ハッシュ モードと履歴モードは似ていますが、ほとんどすべての記事では履歴モードの使用を推奨しています。その理由は、「#」記号が見苦しすぎるためです...0_0 "

醜いハッシュが欲しくない場合は、ルーターの履歴モードを使用できます - 公式ドキュメント

もちろん、厳格な人間として、私たちは技術の質を外見だけで判断すべきではありません。 MDN によると、history.pushState() を呼び出すと、ハッシュを直接変更するよりも次の利点があります。

  • pushState によって設定される新しい URL は、現在の URL と同じオリジンを持つ任意の URL にすることができます。ハッシュは # の後の部分のみを変更できるため、現在の URL と同じドキュメントの URL のみを設定できます。
  • pushState によって設定される新しい URL は、現在の URL とまったく同じであってもよく、この場合もレコードがスタックに追加されます。レコードがスタックに追加されるようにするには、hash によって設定される新しい値が元の値と異なる必要があります。
  • pushStateはstateObjectを通じてレコードに任意のタイプのデータを追加できますが、hashは短い文字列のみを追加できます。
  • pushStateは後で使用するためにタイトル属性を追加で設定できる

履歴モードの問題

シングルページ アプリケーションの場合、理想的な使用シナリオは、アプリケーションに入るときにのみ index.html を読み込み、その後のネットワーク操作は Ajax を通じて完了し、URL に従ってページを再要求しないことです。ただし、ユーザーがアドレス バーに直接入力して Enter キーを押したり、ブラウザーが再起動してアプリケーションを再読み込みしたりするなど、特殊な状況に遭遇することは避けられません。

ハッシュ モードではハッシュ部分の内容のみが変更され、ハッシュ部分は HTTP リクエストに含まれません。

http://oursite.com/#/user/id // 再度リクエストすると、http://oursite.com/ のみが送信されます

したがって、URL に基づいてページをリクエストする場合、ハッシュ モードでは問題は発生しません。

履歴モードでは、URL が通常のリクエスト バックエンドの URL と同じになるように変更されます。

http://oursite.com/user/id

この場合、バックエンドにリクエストを再送信します。バックエンドに、対応する /user/id ルーティング処理が設定されていない場合は、404 エラーが返されます。公式に推奨されている解決策は、すべての状況をカバーするためにサーバー側に候補リソースを追加することです。URL がどの静的リソースとも一致しない場合は、アプリが依存する同じ index.html ページが返される必要があります。また、これを行うと、すべてのパスに対して index.html ファイルが返されるため、サーバーは 404 エラー ページを返さなくなります。これを回避するには、Vue アプリケーション内のすべてのルーティング状況をカバーしてから、404 ページを表示します。あるいは、バックエンドとして Node.js を使用する場合は、サーバー側のルーティングを使用して URL を照合し、一致するルートがない場合は 404 を返すことで、フォールバックを実装できます。

アプリケーションファイルを直接読み込む

ヒント: ビルドされたファイルは、HTTP サーバー経由で提供されることを目的としています。

file:// 経由で index.html を開いても機能しません。

Vue プロジェクトが vue-cli の webpack を通じてパッケージ化された後、コマンド ラインに次のプロンプトが表示されます。通常、開発中であろうとオンライン中であろうと、フロントエンド プロジェクトはサーバーを介してアクセスされ、「file:// で index.html を開く」ことはありません。ただし、プログラマーは皆、要件とシナリオが常に奇妙であることを知っています。製品マネージャーが考えられないことは何もありません。考えられないことだけです。

この記事を書いた当初の目的は、次のような問題に遭遇することでした。モバイル ディスプレイ プロジェクトを迅速に開発する必要があり、WebView を使用して Vue シングル ページ アプリケーションをロードすることにしましたが、バックエンド サーバーが提供されていなかったため、すべてのリソースをローカル ファイル システムからロードする必要がありました。

//Androidアプリラッパー
パブリッククラスMainActivityはAppCompatActivityを拡張します{

    プライベート WebView webView;

    @オーバーライド
    保護されたvoid onCreate(バンドルsavedInstanceState) {
        super.onCreate(保存されたインスタンス状態);

        webView = 新しい WebView(これ);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("file:///android_asset/index.html");
        コンテンツビューを設定します。
    }

    @オーバーライド
    パブリックブールonKeyDown(int keyCode, KeyEventイベント) {
        ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) の場合 {
            webView に戻る();
            true を返します。
        }
        false を返します。
    }
}

この場合は「index.htmlをfile://で開く」必要があるようですので、まずは設定を行う必要があります。

  • プロジェクトのconfig.jsファイルで、assetsPublicPathフィールドの値を相対パス「./」に変更します。
  • 生成された静的フォルダ内の画像などの静的リソースの場所を、コード内の参照アドレスと一致するように調整します。

これは明らかに必要な変更ですが、変更後も正常にロードできません。調査を重ねた結果、プロジェクトの開発時にルーターが履歴モード(美観のため...0_0")に設定されていたことが判明しました。ハッシュモードに変更すると、正常にロードできるようになりました。

なぜこのようなことが起こるのでしょうか?私はその理由を次のように分析しました。

ファイル システムから index.html を直接読み込む場合、URL は次のようになります。

ファイル:///android_asset/index.html

ホームページビューが一致する必要があるパスは、パス: '/' です。

デフォルトの新しいルーターをエクスポートします({
  モード: '履歴'、
  ルート: [
    {
      パス: '/'、
      名前: 'インデックス',
      コンポーネント: IndexView
    }
  ]
})

まず、HTML5History の履歴モードを見てみましょう。

確実にURLをプッシュする(ブール値)
  getLocation(this.base) !== this.current.fullPath の場合 {
    const current = cleanPath(this.base + this.current.fullPath)
    プッシュ? pushState(現在) : replaceState(現在)
  }
}

エクスポート関数 getLocation (base: string): string {
  パス = window.location.pathname とします
  ベース && path.indexOf(base) === 0 の場合
    パス = パス.スライス(ベース.長さ)
  }
  戻り値 (パス || '/') + window.location.search + window.location.hash
}

このロジックは、URL が存在することのみを確認します。パスは、window.location.pathname から切り取って直接取得されます。パスは index.html で終わるため、「/」と一致できず、「file:// で index.html を開いても機能しません」。

ハッシュモードをもう一度見てみましょう。HashHistoryでは次のようになります。

エクスポートクラスHashHistoryはHistoryを拡張します{
  コンストラクタ (ルータ: Router、ベース: ?string、フォールバック: boolean) {
    ...
    スラッシュを保証する()
  }

  // アプリがマウントされるまで遅延されます
  // ハッシュ変更リスナーが早すぎるタイミングで起動されるのを避けるため
  セットアップリスナー() {
    window.addEventListener('ハッシュ変更', () => {
      if (!ensureSlash()) {
        戻る
      }
      ...
    })
  }

  現在の場所を取得します(){
    getHash() を返す
  }
}

関数ensureSlash(): ブール値{
  定数パス = getHash()
  (path.charAt(0) === '/'の場合){
    真を返す
  }
  replaceHash('/' + パス)
  偽を返す
}

エクスポート関数 getHash(): 文字列 {
  定数 href = window.location.href
  定数インデックス = href.indexOf('#')
  インデックス === -1 を返します ? '' : href.slice(index + 1)
}

コード ロジックでは、関数 EnsureSlash() が何度も登場していることがわかります。# 記号の後に '/' が続く場合は true を返し、そうでない場合は '/' が強制的に挿入されます。したがって、ファイル システムから index.html を開いた場合でも、URL は次の形式になることがわかります。

ファイル:///C:/Users/dist/index.html#/

getHash() メソッドによって返されるパスは '/' であり、これはホーム ビューのルートと一致します。

したがって、バックエンド サーバーの助けを借りずにファイル システムから直接 Vue シングルページ アプリケーションをロードする場合は、パッケージ化後のいくつかのパス設定に加えて、vue-router がハッシュ モードを使用していることを確認する必要もあります。

上記は、vue-router の観点から見たフロントエンドルーティングの 2 つの実装の詳細です。vue フロントエンドルーティングの 2 つの実装の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • vue-router フロントエンドルーティングが値を渡す方法の詳細な説明
  • vue-router ソースコードでフロントエンドルーティングを実装する 2 つの方法
  • フロントエンドルーティングとvue-routerの実装原理の簡単な分析
  • vue-cli スキャフォールディングで vue-router フロントエンドルートを構成する
  • vue-routerフック関数はルーティングガードを実装します
  • Vue ルーター vue-router 詳細説明ガイド
  • Vue-routerのハッシュモードと履歴モードの違いの詳細な説明
  • vue-routerはメタ情報メタ操作を定義します
  • vue3.0+vue-router+element-plusの初期練習
  • vue-routerのナビゲーションフック(ナビゲーションガード)の詳しい説明

<<:  linuxdeployqt を使用して Ubuntu で Qt プログラムをパッケージ化する問題を解決する

>>:  Mysql データベースをバージョン 5.6.28 からバージョン 8.0.11 にアップグレードするときにプロジェクトを展開するときに発生する問題と解決策

推薦する

mysqlを使用して、URLから返されたhttp GETリクエストデータを記録します。

ビジネスシナリオの要件と実装ロジックの分析ビジネスでは、HTTP GET を使用してデータを要求する...

VueのTodoListケースの詳しい説明

<テンプレート> <div id="ルート"> <...

相同性とクロスドメイン、jsonp(関数カプセル化)、CORS原則の詳細な分析

目次同一起源ポリシーAjax リクエストの制限: Ajaxは自身のサーバーにのみリクエストを送信でき...

よくあるNginxの設定ミスの例

目次ルートの場所が見つかりませんオフバイスラッシュ安全でない変数の使用スクリプト名$uri を使用す...

Linuxで現在のスクリプトの実際のパスを取得する方法

1. 現在のスクリプトの実際のパスを取得します。 #!/bin/bash if [[ $0 =~ ^...

clearfixとclearの例

この記事では、CSS を理解し始めたばかりの人を対象に、主に HTML で clearfix と c...

Mysqlデータベースの文字化けに対処する方法

MySQL では、データベースの文字化けは一般的に文字セットを設定することで修正できますが、文字化け...

vue keepAlive キャッシュクリア問題事例の詳細な説明

Keepalive は Vue プロジェクトでのキャッシュによく使用され、基本的な要件を満たすのに非...

MySQL 5.7.20\5.7.21 無料インストール版のインストールと設定のチュートリアル

参考までに、mysql 5.7.20 / 5.7.21 をダウンロード、インストール、構成します。具...

Mysql のデッドロックの表示とデッドロックの除去の詳細な説明

序文しばらく前にMysqlのデッドロック問題に遭遇したので、解決しました。問題の説明: Mysql ...

Mysql5.7 サービスを開始できません。グラフィカル ソリューション チュートリアル

p>「サービス」で手動で起動すると、 コンソールから起動します: 次に、...\MySQL S...

Ubuntu 14.04 に FTP サーバーをインストールするための実装手順

目次インストールソフトウェア管理匿名アクセスモード設定ファイルを変更するクライアントがサーバーにログ...

MySQLユーザー削除バグを解決する

著者が MySQL を使用してユーザーを追加していたところ、ユーザー名が間違って記述されていることに...

Docker で nginx の https を設定する方法

https をサポートしていない Web サイトは、ブラウザによって徐々に安全でないとマークされるた...

どのような種類の MYSQL 接続クエリを知っていますか?

序文クエリ情報が複数のテーブルから取得される場合、クエリのためにこれらのテーブルを結合する必要があり...