Vue: 非同期コンポーネントのライフサイクルフックを待つ

作成日 2017ĺš´12月08日  Âˇ  51コメント  Âˇ  ソース: vuejs/vue

この機能はどのような問題を解決しますか?

ユーザーが非同期操作に依存するライフサイクルフックを実装する必要がある場合、vueは実装されたフックの非同期性を尊重し、vueランドでそれを待つ必要があります。

提案されたAPIはどのように見えますか?

APIは変更されません。 非同期フックを待つことによって、現在どのように機能するかだけです。

最も参考になるコメント

これは私が待ち望んでいる実際のコードです:

  beforeMount: async function() {
       this.user = await client.get({type: 'user', id: this.$route.params.id});
    }

これはUserPageコンポーネントの一部になります。

全てのコメント51件

あなたが望んでいるのは

created () {
    return new Promise(resolve => {
        setTimeout(() => {
            console.log('created')
            resolve()
        })
    })
},
mounted () {
    console.log('mounted')
}

表示する

mounted

?

機能リクエストを作成するときは、実際のユースケースを追加して、リクエストを実装する価値があるようにしてください。

これは理論的にはクールなアイデアですが、これを実現するにはアーキテクチャの根本的な再考/書き直しが必要であり、ライフサイクルフックの同期性に依存する多くのロジックを壊す可能性があります。 したがって、その変更を正当化するためには、メリットが大きい必要があります。そうしないと、完全なアップグレードを計画している場合にのみ検討できます。これは、すぐには発生しない可能性があります。

とりあえず締めくくりますが、より具体的な理由/ユースケース/影響についてフォローアップしてください。

@posva理解しました-お詫び申し上げます。 私の実際のユースケースは、ページルートパラメータから( this.$route.paramsを介して) user_idを受け取り、データベースから実際のユーザーデータをフェッチするUserPageコンポーネントがある場合です。次のようなコマンドを使用してサーバー上で:
this.user = await client.get({type: 'user', id: this.$route.params.id})
ここで、 this.userは、 UserPageコンポーネントのdata部分にあるuserフィールドを指します。

理想的には、コンポーネントが作成された後( this.$route.paramsが使用可能になるように)、コンポーネントが実際にマウントされる前にそのコード行を実行して、テンプレートでuser安全に使用できるようにします。未定義の値に関するエラーを取得せずに

@ yyx990803
私はここでは初心者かもしれませんが、Vueランドでmountedなどのライフサイクルフックを呼び出す前にawaitキーワードを追加することだけを変更するべきではありませんか?

これは私が待ち望んでいる実際のコードです:

  beforeMount: async function() {
       this.user = await client.get({type: 'user', id: this.$route.params.id});
    }

これはUserPageコンポーネントの一部になります。

心配ない! 私はそのユースケースを想像していました。 読み込み状態を表示するさまざまな方法が開かれるため、vue-routerのドキュメントで説明されているように処理することをお勧めします。 コンポーネントをレンダリングする前に、データがそこにあるのをすでに待つことができます。

OK、それは理にかなっています。 ただし、ユーザーページの簡略版であるユーザーコンポーネント(たとえば、Facebookでユーザーの名前にカーソルを合わせてプロファイルを「覗く」と表示されるコンポーネントなど)がある場合はどうなりますか?ここでは関係なく、 idはプロパティとしてコンポーネントに渡されます。

ここで全体像を見ると、JavaScriptの関数は同期または非同期のいずれかになり、ライフサイクルフックは関数であり、関数としての考え方は非同期をサポートする必要があります(私のユースケースと直感的な「リーチ」で示されています)。私がここで使用しているアプローチについて)。

あなたはそれをする多くの方法があります。 最も単純な方法は、nullで始まる変数を使用し、データをフェッチして設定し、実際のコンポーネントを切り替えます(v-ifのため)。 よりエキゾチックなバージョンは、コンポーネントを解決して<component :is="myDynamicComp"/>を使用する関数です😄
ただし、問題をハイジャックして質問にしないでください😉フォーラムを使用するか、そのために不和を使用してください

いいえ、私は本当にコードの助けを必要としません! 実際、私はすでにあなたの提案と非常によく似た回避策を実装しています。 私が言おうとしているのは、JS非同期機能を使用する方がはるかに直感的だということです。

私が気付いていなかったのは、非同期コードと同期コードは本質的に根本的に異なるため、同期コードは、それ自体を非同期コードに根本的に変更せずに、非同期コードに強制的に準拠させることはできないということです。 yyx990803はすぐにそれを見ましたが、彼のコメントを完全に理解するのに少し時間がかかりました。 お時間を割いていただきありがとうございます。途中で私の側に誤解があった場合は申し訳ありません。

ここにいくつかのユースケースがあり、いくつかの提案と回避方法を取得したいと思います。

MainPage.vueが私のメインコンテナです。 beforeCreateでajax "/ init"を呼び出してユーザー情報を取得し、Vuex.storeにコミットします。
Content.vueは、 MainPage.vue内の子です。 Vuex.storeからのユーザーの役割に応じて、 mounted段階でさまざまなAPI呼び出しを呼び出したいと思います。

async / awaitフローでのライフサイクル呼び出しの場合、順序に従います。
親beforeCreate->親作成->子beforeCreate->子作成->子マウント....(コンポーネントのライフサイクルについて正しく理解している場合)。

しかし、現在Content.vueでユーザー情報を取得できません。どうすれば回避策を​​入手できますか?
「/ init」APIは多くのページ(Vue-Routerのコンテナー)で使用されているため、 MainPage.vue内で呼び出されたままにしておきたいと思います。

stackoverflowに質問を投稿しました

ありがとう

価値のあるものに対するハックの回避策:

{
  created: function(){
    this.waitData = asyncCall();
  },
  mounted: function(){
    this.waitData.then(function(data) { ... })
  }
}


考えられるより「フラットな」ソリューション:

{
    async created () {
        let createdResolve = null
        let createdReject = null
        this.createdPromise = new Promise(function(resolve, reject){
            createdResolve = resolve
            createdReject = reject
        })
        await asyncCall1()
        await asyncCall2()
        ...
        createdResolve(someResult)
    }
    async mounted () {
        let result = await this.createdPromise
        ...
    }
    data () {
        return {
            createdPromise: null
        }
    }
}

これはまだ問題ではありませんか?

data() {
 ...
},
async created() {
  const something = await exampleMethod();
  console.log(something);
}

私のために働いています( @fifmanが言及しているように)。

@breadadamsはい、もちろんです。 createdメソッドの_inside_関数が待機されますが、 createdまたはmounted関数自体は待機されません。

したがって、Vueインスタンスはcreatedを呼び出し、 createdで長時間実行されているプロセスが終了する前に、即座にmountedを呼び出します。

ああ、私の悪い@ darren-dev-私の側では異なるユースケースですが、今は問題が発生しています😅明確にしてくれてありがとう。

@breadadamsまったく問題ありません-私たち全員が私たち自身のケースのためにここにいます、私が明確にすることができてうれしいです!

非同期ライフサイクルフックは、次のメジャーバージョンで優れた実装になる可能性があります

ライフサイクルメソッドの非同期サポートを許可すると、デフォルトで悪いUXプラクティスが助長されるように思われます。 どのように? 非同期機能は、すぐに完了できないリクエスト(長時間実行リクエストやネットワークリクエストなど)に使用されます。 Vueに、作成やマウント、またはその他のライフサイクルメソッドのいずれかをネットワーク要求または長時間実行される非同期プロセスで待機するように強制すると、ユーザーに顕著な影響を与えます。 ユーザーがサイトにアクセスし、コンポーネントがユーザーのむらのあるセル接続がネットワーク要求を完了するのを待つ間、空白の画面で4秒間待機する必要があると想像してください。 また、これはユーザーに悪影響を与えるだけでなく、状況の制御を犠牲にします。開発者として、ユーザーがロード時間を認識できるようにしたり、進行状況インジケーターを確定または不確定に表示したりするためにできることは何もありません。 したがって、この機能をVueに組み込むことで、Webをより良い場所にすることはできません。 あなたは悪い習慣を可能にしている。

最初から非同期の場合の計画と設計を行う方がはるかに優れています。非同期プロセスをcreatedまたはmountedなどで開始し、コンポーネントをスケルトン構造にするか、最悪の場合はAPIがユーザーの権限を返すのを待つ間、スピナー。 はるかに優れたUXであり、コントロールを犠牲にすることはありません。 また、Vueは非同期ライフサイクル関数を処理するためのコードを追加する必要がないため、バンドルを小さく保つことができます。 勝つ勝つ。

@seanfisherあなたは有効なポイントを上げます。 アーキテクチャ的に言えば、非同期のイベントセットを中心とした設計は、開発者が処理する必要があります。これが、メッセージを正しく表現する唯一の方法だからです。

免責事項:以下は、ページ生成の考え方を念頭に置いて書かれています。 私の議論が無効である確かに有効なユースケースがあります。


ただし、開発者のデザインパターンの決定は、使用しているフレームワークに任せるべきではありません。 私の主張は、フェーズが完了するのを待っていないのなら、なぜ異なるフェーズがあるのか​​ということです。 なぜステージを作成してからマウントしたのですか? 基本的にすべてが一度に行われている場合は、作成されたステージを完全に無視しても問題ありません。

文字通り、私が(初期のVue以来)作成に夢中になったのは、信頼する必要のあるVueを注入しなければならなかったときだけでした-それは私のページのセットアップやレイアウトとは何の関係もありませんでした。 ただし、(短い)非同期タスクが実行されるのを待たなければなりませんでした。これは、ページがレンダリングされる前に(Firebaseの認証方法にフックするなど)はるかに優れています。 それを作成し、マウントする前に完了するのを待つことで、ハッキーな回避策の必要性を完全に減らすことができます。

覚えておいてください、私の主張は、VueはImが間違って開発していることを私に教えてはならないということです。 必要な機能を提供するだけです。

ただし、開発者のデザインパターンの決定は、使用しているフレームワークに任せるべきではありません。

ええと...フレームワークは、開発者を特定のデザインパターンとプラクティスに具体的に制限またはガイドまたは「フレーム化」するように構築されています。 それが彼らの主な目的です。 優れたフレームワークはどれもスマートAPIを提供します。これは、フレームワークを操作するための明確で明白な方法を正確に提供しますが、それでも制約があります。

はい、フレームワークが特定の機能を提供すると同時に、開発者を特定の設計手法に制約することは逆説的です。 それこそが、フレームワーク内の意見がそれを助けたり傷つけたりする可能性がある場所です。 適切なバランスを見つけるのは難しいです。Vueというか、EvanとVue開発チームは、これらの判断を下すために素晴らしい仕事をしてきたと思います。

スコット

適切に設計されたフレームワークを同じデザインパターンで拡張する必要があるとは決して主張しませんが、私の主張は、フレームワークがそれを指示できないということです。 あなたは正しいですが、フレームワークがどれほど優れていても、エンド開発者は彼らが望むことを何でもするためにオープンでなければならないと言っています。

しかし、作成およびマウントされたイベントを非同期にするという_実際の_議論には触れていません。私の意見にあなたの意見を追加しただけです(これは間違いではありません)。これは一般に大きな脱線につながります。

適切に設計されたフレームワークを同じデザインパターンで拡張する必要があるとは決して主張しませんが、私の主張は、フレームワークがそれを指示できないということです。

申し訳ありませんが、これは私には意味がありません。 どのように拡張するかを指示しないフレームワークを1つ見せてください。

「エヴァンと共同で良い判断を下す」ということわざが私の意見を示していると思いました。 しかし、より明確にするために。 マウントおよび作成されたライフサイクルフックは、非同期で動作する必要はありません。同期で動作するという事実は、アプリケーションロジックについての推論に役立ちます。 とにかく「待機中」はUIで考慮する必要があり、非同期コードは引き続き各フックで実行できます。 beforeMountフックとmountフックが必要になったことについて議論することができます。 ただし、コンパイルされたレンダリング関数のように、マウント時に必要なものが1つか2つある場合があります。たとえば、作成されたものではまだアクセスできません。

スコット

Vueが非同期ライフサイクルフックについて何らかの意見を持っている場合、それは推測の問題ではありません。 Vueが採用、提供、または推奨する標準、API、ガイド、およびベストプラクティスが、いつすべての人に読めるようになるかを推測する必要はありません。

Evanの最初の回答では、非同期ライフサイクルフックは標準APIに含まれていません。これは、必ずしも悪い考えではなく、実装のコストを正当化するのに十分なメリットがないためです。

何かが起こっていることを示すことなく、ユーザーに非同期createdまたは他のライフサイクルフックを待たせるのは悪い習慣であるという意見については、非同期フックをサポートしていたVueが今では多分問題を解決する(そして実装が簡単な)「フェーズテンプレート」と呼ばれるものを提供します。

何かが起こっていることを示すものなしに、非同期が作成されるか、他のライフサイクルフックをユーザーに待たせるのは悪い習慣であるという意見については、

これは本当に問題ですか?

スコット

これが私が抱えている問題です-そして、これは問題があるように見えるので、誰かが私がこれをどのように行うべきかを提案することができます。

私たちのVueアプリケーション(かなり大きい)はVuexを広範囲に使用しています。 create()ライフサイクルのVueコンポーネントのかなりの数で、store.dispatch()を介してストア内のいくつかのアイテムを設定しました(明らかに)。 ただし、私の注意を引いたので、store.dispatch()は、基になるロジックと関数が非同期でない場合でも、常にpromiseを返します。 だから私はasynccreated(){await store.dispatch( 'foo / action')}を入れましたが、前述のように実際には失敗します..

私もTypescriptを使用していますが、待っていないときはかなりひどく文句を言います/ .thestore.dispatch()は..「フローティング」プロミスを持っています。

では、Vuex store.dispatch()を非同期にできない場合に、ライフサイクルで使用するための最良の方法は何でしょうか。

乾杯!!

vueの特定の意見に関する他のすべての議論、およびフレームワークが意見を脇に置くべきかどうかについては、この動作をより明確に文書化することが有益である可能性があります。

上記の@fifmanの「よりフラットな」ソリューションを見ていますが、それが問題を解決するかどうかはmounted()が戻るまでにXHRを確実にロードできます。 そのソリューションでは、 created()とmounted()両方が非同期であるため、Vueはそれぞれを呼び出し、非同期処理がバックグラウンドで実行されている状態で、多かれ少なかれすぐに戻ります。 実際、 createdPromiseを廃止し、 created()またはmounted()いずれかですべての非同期作業を行うよりも、次のようにそれがどのように優れているかはわかりません。

async mounted() {
  let response = await fetch(my_url)
  let data = await response.text()
  my_data_member = data
}

いずれにせよ、 my_data_member mounted()がPromiseを返した後、XHRが完了すると、 my_data_memberは「後で」入力されます。

ルートコンポーネント<div id="app"/>でv-ifを使用して、データの読み込みが完了したときにトリガーすることもできます。 たとえば、リフレッシュトークンに使用します。

これは、多くのユースケースを持つ優れた機能です。 私のユースケースでは、コンポーネントを実際にレンダリングする前に、特定のAPIプロパティをロードする必要があります。 ただし、ライフサイクルフックの非同期が理想的なソリューションであるとは思いません。

現在、誰もがここで非同期関数がスムーズに実行される完璧なシナリオについて言及しています。 ただし、たとえば、ユーザーの接続が遅いか遅れている場合、APIの応答後にコンポーネントがマウントされるのを待つと、コンポーネントのライフサイクル全体が分散されます。 読み込み情報をユーザーに表示することはできません。 さらに悪いことに、APIがタイムアウトしたりエラーを返したりすると、アプリケーションはマウントされずにハングします。

これは優れた機能ですが、ドメインロジックの実装では、フレームワークよりも基盤となるロジックについての洞察が多く、副作用が少ないため、フレームワークではなくアプリケーションで処理することをお勧めします。

この機能の+1。
さまざまなコンポーネントで使用されるミックスインがあります。ミックスインは、マウントされたフックのデータベースからデータをフェッチします。
コンポーネントは、マウントされたフックでもミックスインによってフェッチされたデータを処理する必要があります。
現在のように、ミックスインがデータのロードを終了したときに呼び出されるコールバックを実装し、コンポーネントにマウントされたフックを破棄する必要がありました。
それは機能しますが、マウントされたフックが約束を処理した場合はよりきれいになります。

@cederronは純粋に興味がないのですが、親コンポーネントのデータをダウンロードして小道具として渡せないのはなぜですか? v-ifを使用して、データの読み込み中に読み込みインジケーターを表示します。データが表示されたら、コンポーネントを表示できます。コンポーネントが作成されると、必要なすべてのデータが含まれます。

コンポーネントが2つの異なる無関係な状態を表すことを回避します(「データがロードされていない、待機中」および「データがロードされている、操作可能」)

複数の場所でロジックを再利用する必要がある場合、ダウンロードロジックをVuexに移動する場合もあります。データのダウンロードは、コンポーネントではなくVuexアクションで行われるため、ちょっと意味があります。

@ReinisVケースを単純化しすぎたと思います。コンポーネントは、ミックスインにマウントされたフックによってフェッチされたデータから新しいデータを作成し、コンポーネントビューはこの新しいデータにバインドされます。
したがって、ミックスインはデータベースからデータをフェッチする必要があります>コンポーネントはデータベースからデータを作成します>これでコンポーネントが表示されます

これは機能しません。

export const MyMixin = {
    data: function () {
        return {
            dbData: null
        }
    },
   mounted:  async function () {
      this.dbData = await asyncFetchDataFromDB()
   }
}


export const MyComponent = {
    mixins: [MyMixin],
    data: function () {
        return {
            newData: null
        }
    },
   mounted:  function () {
      this.newData = handleDBData(this.dbData)
   }
}

コンポーネントマウントフックでは、dbDataはnullになります。

現在、ミックスインがデータをフェッチするときにコールバックを実行しますが、マウント関数を非同期にする方がきれいです。

私はそれを使用していないので、vuexについて多くを言うことはできません

@seanfisherがここで言及したことを本当に繰り返したいと思います。 非同期としてマークされたコンポーネントをvueで待機させると、ユーザーに問題が発生するだけでなく、async / awaitを使用してデータ検索を開始するパターンがいたるところに存在します。 これらのライフサイクルフックのコードを、vueのブロックを明示的に回避するために、予期しない約束に明示的に変換することを強制します。 場合によってはそれが良いかもしれません。機能が導入される場合は、2つのライフサイクルを同時に実行することを提案する必要があります。現在のライフサイクルはコンポーネントフックの実行を処理し、もう1つはグローバルコールバックの実行を待機します。

しかし、vueのブロックを回避するために、ライフサイクルフックのすべてを文字通り書き直すことに本当に失望します。 async/awaitははるかにクリーンなので、promiseは使用しません。 下位互換性のない方法でこれを変更すると、失敗のピットの成功のピット(待機されていないコンポーネントのライフサイクル)が変更されます。

最初から非同期の場合の計画と設計を行う方がはるかに優れています。非同期プロセスをcreatedまたはmountedなどで開始し、コンポーネントをスケルトン構造にするか、最悪の場合はAPIがユーザーの権限を返すのを待つ間、スピナー。 はるかに優れたUXであり、コントロールを犠牲にすることはありません。 また、Vueは非同期ライフサイクル関数を処理するためのコードを追加する必要がないため、バンドルを小さく保つことができます。 勝つ勝つ。

@seanfisherありがとう、これは

代わりに非同期コンポーネントを使用しないのはなぜですか。非同期コンポーネントは、非同期呼び出しが戻ったときにのみレンダリングされます。
APIの詳細はこちら
https://vuejs.org/v2/guide/components-dynamic-async.html#Async -Components

new Vue({
  components: {
    root: () => ({ // Aync component
      // The component to load (should be a Promise)
      component: new Promise(async function (resolve) {
        await FetchMyVariables()
        resolve(MyComponent) // MyComponent will be rendered only when FetchMyVariables has returned
      }),
      // A component to use while the async component is loading
      loading: { render: (h) => h('div', 'loading') }, 
    })
  },
  render: h => h('root')
})

これらのソリューションのほとんどは問題ないように見えますが、これはVueの主要な欠落部分の1つであり、非常に直感的です。 async awaitの使用が日常茶飯事になっているので、Vue3はこれを実装する必要があると思います。 どうぞ@ yyx990803あなた、

これが尊重されていないことを確認してコードをリファクタリングしますが、ハックになるため、醜いコードが出てきます。

ライフサイクルメソッドの非同期サポートを許可すると、デフォルトで悪いUXプラクティスが助長されるように思われます。 どのように? 非同期機能は、すぐに完了できないリクエスト(長時間実行リクエストやネットワークリクエストなど)に使用されます。 Vueに、作成やマウント、またはその他のライフサイクルメソッドのいずれかをネットワーク要求または長時間実行される非同期プロセスで待機するように強制すると、ユーザーに顕著な影響を与えます。 ユーザーがサイトにアクセスし、コンポーネントがユーザーのむらのあるセル接続がネットワーク要求を完了するのを待つ間、空白の画面で4秒間待機する必要があると想像してください。 また、これはユーザーに悪影響を与えるだけでなく、状況の制御を犠牲にします。開発者として、ユーザーがロード時間を認識できるようにしたり、進行状況インジケーターを確定または不確定に表示したりするためにできることは何もありません。 したがって、この機能をVueに組み込むことで、Webをより良い場所にすることはできません。 あなたは悪い習慣を可能にしている。

最初から非同期の場合の計画と設計を行う方がはるかに優れています。非同期プロセスをcreatedまたはmountedなどで開始し、コンポーネントをスケルトン構造にするか、最悪の場合はAPIがユーザーの権限を返すのを待つ間、スピナー。 はるかに優れたUXであり、コントロールを犠牲にすることはありません。 また、Vueは非同期ライフサイクル関数を処理するためのコードを追加する必要がないため、バンドルを小さく保つことができます。 勝つ勝つ。

数千の意見。 コンポーネントのレンダリングが遅れているというシナリオが、ポジティブなユーザーエクスペリエンスと共存できるというシナリオを想像できないからといって、それが存在しないことを意味するわけではありません。

フレームワークが開発者と戦う場合、開発者は別のフレームワークを見つけるでしょう。

@ robob4him

数千の意見。 コンポーネントのレンダリングが遅れているというシナリオが、ポジティブなユーザーエクスペリエンスと共存できるというシナリオを想像できないからといって、それが存在しないことを意味するわけではありません。

フレームワークが開発者と戦う場合、開発者は別のフレームワークを見つけるでしょう

あなたは絶対に正しいですが、ここであなたが共有したものは、何らかの方法で問題を解決するための有効な議論ではありません。 コミュニティに機能の開発を強制するための恐ろしい戦術を導入しました。 会話の建設的な継続ではありません。

@wparad 、それは絶対に恐ろしい戦術ですが、誰かに何かをさせることはありません。 機能が悪い習慣やアンチパターンをサポートしている、または開発者のより大きなコミュニティを崩壊させるという議論をすることは、同じように恐ろしい戦術です。

文字通りあらゆるフレームワーク/言語の機能の半分は開発者にとって危険です。 パブリックメソッドは拡張でき、Vueは要素($ el)などへのアクセスを推奨します。1日の終わりに開発者が仕事を終わらせる必要があるため、フレームワークはこれらを提供します。

この機能リクエストは1年前のものです。 人々は、その理由が実際には悪い習慣を引き起こすからではなく、レンダリングの遅延を悪い習慣として認識してはならないことを理解する必要があります。

vueでrequirejsを使用する必要があります。 私はrequirejsが好きというわけではありませんが、すべてのモジュールをAMDモジュールとして持つオープンソースのLMSでvueを使用したいからです。 beforeCreateフックに必要なすべてのライブラリをロードできれば素晴らしいと思います。 現時点での私にとっての代替手段は、それらをvueの外にロードしてから、より厄介な場所に渡すことです。

ライフサイクルメソッドの非同期サポートを許可すると、デフォルトで悪いUXプラクティスが助長されるように思われます。 どのように? 非同期機能は、すぐに完了できないリクエスト(長時間実行リクエストやネットワークリクエストなど)に使用されます。 Vueに、作成やマウント、またはその他のライフサイクルメソッドのいずれかをネットワーク要求または長時間実行される非同期プロセスで待機するように強制すると、ユーザーに顕著な影響を与えます。 ユーザーがサイトにアクセスし、コンポーネントがユーザーのむらのあるセル接続がネットワーク要求を完了するのを待つ間、空白の画面で4秒間待機する必要があると想像してください。 また、これはユーザーに悪影響を与えるだけでなく、状況の制御を犠牲にします。開発者として、ユーザーがロード時間を認識できるようにしたり、進行状況インジケーターを確定または不確定に表示したりするためにできることは何もありません。 したがって、この機能をVueに組み込むことで、Webをより良い場所にすることはできません。 あなたは悪い習慣を可能にしている。

最初から非同期の場合の計画と設計を行う方がはるかに優れています。非同期プロセスをcreatedまたはmountedなどで開始し、コンポーネントをスケルトン構造にするか、最悪の場合はAPIがユーザーの権限を返すのを待つ間、スピナー。 はるかに優れたUXであり、コントロールを犠牲にすることはありません。 また、Vueは非同期ライフサイクル関数を処理するためのコードを追加する必要がないため、バンドルを小さく保つことができます。 勝つ勝つ。

あなたが言っていることは、 v-if/v-clock/v-show機能を追加すると悪い習慣が助長されるので、それらの機能を削除することでフレームワークを確実に確実にするようなものです。 次に、複雑なアプローチを使用して同じことを行い、これら3つのディレクティブを配置しないためにVueが小さくなるようにします。 最初の開発者は愚かではありません。 2番目のフールプルーフは、フレームワークの使いやすさを制限します。これは、明らかな「フール」に基づいて実行できることを制限しているためです。 画面全体を空白のままにして、非同期操作でWebサイト全体をブロックするためにWebサイト全体にv-ifを設定するのはなぜですか?

ほとんどのユースケースが空白のページでさえないかもしれないという事実をあなたは無視していると思います。 それらは、理由からコンポーネントと呼ばれv-if 、たとえばasync functionsなどを尊重する必要があります。 私はこれを探してVueドキュメント全体をかすめ、最終的に上記のハックの例のようにそれほどきれいではない回避策でそれを行いました。

私が心配しているのは誰か/後でさえ私がコードを維持していることです。 それは、Promiseコールバック地獄vs非同期のようなものです...待ってください。

実際、フレームワークの柔軟性と制御性が簡単にフォローアップできるようになっていると思います。 上記のハックを見て、私が何を意味するのかを確認してください。 開発者は、たとえば単純なasync mounted () { await... }ステートメントのギャップを埋めるためだけにすべてのことを行っています。 これらの機能を使用したくない場合は、関数をasyncとして定義しないか、 awaitをまったく使用しないでください。

実際、 async mountedライフサイクルフックを実際に使用する人は、自分が何をしているのか、なぜそれを行うのかを理解している可能性が高く、心配している悪い習慣を作らない可能性があります。

@emahuni 、あなたが共有している期待に異議を唱える人はいないと思いますが、ニュアンスがあると思います。それはasync mountedまたはasync createdがコンポーネントのレンダリングを遅らせると仮定しましょう。 この場合、親は何をしますか? それをしますか:

  • ブロックも
  • コンポーネントの読み込みが完了するまで、コンポーネントがDOM v-ifから削除されることを想定しています。
  • 読み込みが完了するまでコンポーネントが非表示になることを想定しています
  • その場所に一時的な要素を表示しますか?

動的にロードされるコンポーネントに関する期待は一貫していることに同意しますが、親の動作はそうではないと思います。 このような場合、IMOが子の実装を親に公開し、親にその動的コンポーネントをどう処理するかを理解させることになります。 代わりに、データのロード方法と子コンポーネントの状態は子次第である必要があります。 非同期をロードする場合は、その場所で何をレンダリングする必要があるか(またはレンダリングしないか)をVueに説明する方法が必要です。 これを処理する最良の方法は、新しい複雑さを導入するのではなく、フレームワークがすでに機能している方法です。

さらに、私はあなたの議論に完全には従っていません:

あなたが言っていることは、v-if / v-clock / v-show機能を追加することは悪い習慣を助長するので、それらの機能を削除することによってフレームワークをより確実にフールプルーフするようなものです

この場合、マウントを待機している、または作成された非同期コンポーネントを導入すると、悪い習慣それらをv-ifなどによって作成されている悪い慣行を知っている場合...それを正当化として使用しようとするのではなく、それらの問題が何であるかを明示的に(もちろん別の問題で)共有することをお勧めします別の議論のために。

@emahuni 、あなたが共有している期待に異議を唱える人はいないと思いますが、ニュアンスがあると思います。それはasync mountedまたはasync createdがコンポーネントのレンダリングを遅らせると仮定しましょう。 この場合、親は何をしますか? それをしますか:

  • ブロックも

親は子供を待たずに先に進んでレンダリングすることができますが、なぜそれが必要なのですか? 子がレンダリングすると、すぐに実行してupdatedを実行できます。

  • コンポーネントの読み込みが完了するまで、コンポーネントがDOM v-ifから削除されることを想定しています。

これを取得できるかどうかはわかりません...しかし、答えはノーです。削除されるとは想定していません。マウント中に何かを実行する必要があり、その間にブロックマウントする必要があります。 そのために上記で読んだ多くのユースケースがあります。

  • 読み込みが完了するまでコンポーネントが非表示になることを想定しています

これは、開発者、マウントされたフックまたはその他のフックを同期している理由によって異なります。

  • その場所に一時的な要素を表示しますか?

そうではないかもしれません。 繰り返しますが、それは開発者が何を達成しようとしているのかによって異なります。 重要なのは、ストレートジャケットは何もすべきではないということです。 たとえば、 v-ifが設計されたとき、それは、誰かがコンポーネントのレンダリングを毎回ブロックしたい理由と、代わりに何を配置してそれをだまし取らないかを考えたからではありませんでした。 開発者の設計によるv-ifうまくいかないことがたくさんあります。 その間に画面に何が表示されるかを心配する必要はありません。フレームワークが心配する必要はありません。

動的にロードされるコンポーネントに関する期待は一貫していることに同意しますが、親の動作はそうではないと思います。 このような場合、IMOが子の実装を親に公開し、親にその動的コンポーネントをどう処理するかを理解させることになります。 代わりに、データのロード方法と子コンポーネントの状態は子次第である必要があります。 非同期をロードする場合は、その場所で何をレンダリングする必要があるか(またはレンダリングしないか)をVueに説明する方法が必要です。 これを処理する最良の方法は、新しい複雑さを導入するのではなく、フレームワークがすでに機能している方法です。

参考:これを実装する必要があることに同意しますが、それはあなたが叫んでいるこれらの複雑さを導入し、Vue 3ではなく、破壊的な変更が導入されたときに後で行われる可能性があると彼は感じています。 。

さらに、私はあなたの議論に完全には従っていません:

あなたが言っていることは、v-if / v-clock / v-show機能を追加することは悪い習慣を助長するので、それらの機能を削除することによってフレームワークをより確実にフールプルーフするようなものです

この場合、マウントを待機している、または作成された非同期コンポーネントを導入すると、悪い習慣それらをv-ifなどによって作成されている悪い慣行を知っている場合...それを正当化として使用しようとするのではなく、それらの問題が何であるかを明示的に(もちろん別の問題で)共有することをお勧めします別の議論のために。

async...について言っていたのと同様に、コンポーネントのレンダリングをブロックするために誤って使用される可能性のある機能の例として、これらのディレクティブを指摘しただけです。 彼らには何の問題もありません。 では、誰かが「悪い習慣」を使って空白ページを1分間表示するコンポーネントを作成できるという理由だけで、これらのディレクティブを削除する必要がありますか? ひどいように最悪の例を挙げようとしない限り、実際にはそれが起こらないので誰もそれをしているのを見ません。

重要なのは、まだユースケースが見当たらない場合は、他の人がそれをひどく使用するとは言わないでください。したがって、それを行うべきではありません。 悪い習慣は無知の問題であり、無知な人はこれらの機能を完全に使用することは決してありません。

誰かがこのhttps://github.com/vuejs/vue/issues/7209#issuecomment-424349370を尋ねましたが、私が見た限りでは誰も彼に答えませんでした。 これは、Vueがこの部分で遅れを取っていることを真に示しています。 アーキテクチャのこの部分は、非同期がまだ問題にならないときに設計されました。 したがって、最新のアーキテクチャの最新の要件を満たすように更新することは、確かに良い考えです。 それ以外の場合、残りはハックであり、業界で起こっていることを行うのではなく、それを行うための特定の方法を必要とする回避策です。

ただし、まだわかりませんが、新しい機能APIを一目で見ると、実際にこれが可能であるように思われます。 機能的であるため、非同期ライフサイクルフックなど、客観的に実行できなかった特定のことを実行できることを意味します。

重要なのは、まだユースケースが見当たらない場合は、他の人がそれをひどく使用するとは言わないでください。したがって、それを行うべきではありません。 悪い習慣は無知の問題であり、無知な人はこれらの機能を完全に使用することは決してありません。

その点を指摘したことはありません。コンポーネントのレンダリングをブロックすることなく、デフォルトで非同期アクションを実行したいという点を指摘しています。 mountedまたはcreatedブロックでasyncアクションを実行すると、コンポーネントのレンダリングが遅れるのは直感的ではありません。 これが事実であると仮定すると、代わりに、現在の機能を望んでいる消費者がどのように進むかによって複雑さが生じることがわかります。 これまでの議論は、求められていることはできないということではなく、求められていることがデフォルトであるべきだということです。 v-if="loaded"基づいて表示されたテンプレートを切り替えることで、コンポーネントのレンダリングをすでにブロックできます。

現在、コードをブロックせずにレンダリングするには、次のようになります。
現在、そのコードは次のとおりです。

<template>
  <div>  
    <spinner v-if="!loaded">
    <div v-else>
      ....
    </div>
</template>

<script>
  async created() { 
    await this.loadData();
    this.loaded = true;
  }
</script>

また、実際にブロックすることはできないため、ブロックを使用してレンダリングすることはまったく同じように見えます。 async created()実際にコンポーネントをブロックしたと仮定します。 次に、コードを分離します。 スピナーを表示するには、次のように記述します。

<template>
  <div>  
    <spinner v-if="!loaded">
    <div v-else>
      ....
    </div>
</template>

<script>
  created() { 
    this.loadData().then(() => this.loaded = true);
  }
</script>

作成した画面でのコンポーネントのレンダリングは無視してください

<template>
  <div>  
    <div>
      ....
    </div>
</template>

<script>
  async created() { 
    await this.loadData();
  }
</script>

レンダリングをブロックするためにこの単純化を追加すると、ブロックをより複雑にしないことが保証されるという利点は何ですか? 私はそれを見ていません。

コンポーネントの依存関係の処理

@ yyx990803これを見てください。完璧ではありませんが、それでも複雑なユースケースのシーンです。

ライフサイクルフックに非同期があった場合にエレガントに処理できた可能性のあるユースケースを次に示します...待機:
_私は実際にアプリでこれを実行したいと思っていましたが、これを実現するために醜いコードを入手しました。 これはcoz_の非常に不自然な例です

コンポーネントB && Cのmountedフックが起動するのを待ってから、mountedは、そのcreatedフックを待機する必要があります。これにより、トリガーを待機していたコンポーネントB && Cのマウントがトリガーされました_(待機する前に実際に何かを実行できます)_。 関係するコンポーネントのすべてが1つの場所にとどまるため、この方法の方が簡単で、はるかにクリーンで直感的です。

Aはトリガーイベントを発行し、 BとCからの応答をリッスンします_( BとCは続行する前にAの信号を待機し、マウントされるとイベントを発行します)_続行する前に単純です。 これは、状態管理のために他の場所に無関係なデータが散らばっていない

メインホスティングコンポーネント、すべてのコンポーネントが一緒にロードされますが、イベントと非同期を使用して適切なコンポーネントを待ちます...待ってください。 それはこれらの子供たちが何をするかをあまり気にしません、彼らは彼ら自身を注文します。

<template>
  <div>
     ...
     <component-A/>
     <component-B/>
     <component-C/>
     ... other conent
  </div>
</template>
<script>
  import ComponentA...
  ...
  export default {
      components: { ComponentA... }
  }
</script>

コンポーネントAは、依存関係としてBとCのマウントを制御します。 トリガーは、後で他のフックで実行することも、同じコンポーネントのUXイベントを介して実行することもできます。 以下は、ここでアイデアを披露するためのものです。

<template>
  ...
</template>
<script>
  export default {
      async created() {
          // ...do something here before mounting thrusters, even await it
         this.root.$emit('mount-thrusters');
         await Promise.all([
            this.wasMounted('thruster-1-mounted'), 
            this.wasMounted('thruster-2-mounted')
         ]); 
      },
      mounted() {
        // will only run after components B and C have mounted
        ...
      },

     methods: {
       wasMounted(compEvent) {
          return new Promise( (resolve)=>this.root.$once(compEvent, ()=>resolve()));
       }
    }
  }
</script>

コンポーネントB

<template>
  ...
</template>
<script>
  export default {
      async created() {
          // ...do something here, even await it, but happens at the same time as all components
         await new Promise( (resolve)=>this.root.$once('mount-thrusters', ()=>resolve()));
      },
     mounted() {
       this.root.$emit('thruster-1-mounted');
    }
  }
</script>

コンポーネントC

<template>
  ...
</template>
<script>
  export default {
      async created() {
          // ...do something here, even await it, but happens at the same time as all components
         await new Promise( (resolve)=>this.root.$once('mount-thrusters', ()=>resolve()));
      },
     mounted() {
       this.root.$emit('thruster-2-mounted');
    }
  }
</script>

上記のコードは、重複するコードスニペットがたくさんあることを確認するためにミックスインを使用することでさらに簡略化できます。明確にしたかっただけです。 wasMountedメソッドは、ミックスインで缶詰にして、3つのコンポーネントすべてで使用できます。

ここでは、まったく同じことを制御するために他の場所に散らばっている他のハックやルーターコードなしで、各コンポーネントが何を期待しているのかを明確に確認できます。 この機能なしで実際にこれを行うのは非常に混乱します。私がアプリでこれを行ったと信じてください。

これは明らかに、不必要に複雑で保守不可能なコードを取り除きます。

動作が異なる32個のスラスターコンポーネントを備えた大規模なアプリでこれを想像してみてください。 心に留めておくべきポイントは約3つだけです。これは、ミックスインを投入した場合でも2つに減らすことができます。

物事を新鮮に保つ

cozの場合、これはマウントおよび作成に限定されるだけでなく、実際には他のすべてのライフサイクルフックで機能するはずです。 これが光沢のある新しいbeforeActivate / beforeUpdateフックにあると想像してみてください。 私たちは、コンポーネントを作ることができるのawait _activation / update_のみ_activate / update_リフレッシュは、コンポーネントが_activated / updated_をするたびに実行されたときに、 物事が新鮮なままであることを確認します。

これが実装されると、リストは無限になります。

重要なのは、まだユースケースが見当たらない場合は、他の人がそれをひどく使用するとは言わないでください。したがって、それを行うべきではありません。 悪い習慣は無知の問題であり、無知な人はこれらの機能を完全に使用することは決してありません。

その点を指摘したことはありません。コンポーネントのレンダリングをブロックすることなく、デフォルトで非同期アクションを実行したいという点を指摘しています。 mountedまたはcreatedブロックでasyncアクションを実行すると、コンポーネントのレンダリングが遅れるのは直感的ではありません。 これが事実であると仮定すると、代わりに、現在の機能を望んでいる消費者がどのように進むかによって複雑さが生じることがわかります。 これまでの議論は、求められていることはできないということではなく、求められていることがデフォルトであるべきだということです。 v-if="loaded"基づいて表示されたテンプレートを切り替えることで、コンポーネントのレンダリングをすでにブロックできます。

現在、コードをブロックせずにレンダリングするには、次のようになります。
現在、そのコードは次のとおりです。

<template>
  <div>  
    <spinner v-if="!loaded">
    <div v-else>
      ....
    </div>
</template>

<script>
  async created() { 
    await this.loadData();
    this.loaded = true;
  }
</script>

また、実際にブロックすることはできないため、ブロックを使用してレンダリングすることはまったく同じように見えます。 async created()実際にコンポーネントをブロックしたと仮定します。 次に、コードを分離します。 スピナーを表示するには、次のように記述します。

<template>
  <div>  
    <spinner v-if="!loaded">
    <div v-else>
      ....
    </div>
</template>

<script>
  created() { 
    this.loadData().then(() => this.loaded = true);
  }
</script>

作成した画面でのコンポーネントのレンダリングは無視してください

<template>
  <div>  
    <div>
      ....
    </div>
</template>

<script>
  async created() { 
    await this.loadData();
  }
</script>

レンダリングをブロックするためにこの単純化を追加すると、ブロックをより複雑にしないことが保証されるという利点は何ですか? 私はそれを見ていません。

これはVue101ブートキャンプであり、そこに新しいものは何もありません...たとえば上記のケースをカバーするのに十分ではありません。 ここでの考え方は、Vueが実際に使用されているユーザーランドの複雑さを軽減し、コードについて推論しやすくすることです。

ここでのレンダリングは問題ではありません。実際に重要なのは、レンダリングの前に起こっていることです。 コンポーネントを続行またはレンダリングする前に、自由に操作できるようにします。 とにかく、これもレンダリングのブロックとはまったく関係ありません。 Vueがサポートするライフサイクルフックはたくさんあり、他のフックに対して非同期コードを処理する方法があれば、これらは実際に役立つ可能性があります。 アイデアは、次のフック関数に進む前に、Vueが内部的に非同期を尊重することです。

私はこれに本当に混乱しています。BとCをAに結合する代わりに、コードを移動して「AをA.jsにロード」してから、A.jsに「B.data」と「C.data」を更新させます。 。 そうすれば、何らかの理由でA.dataが変更された場合、他のコンポーネントは委任しようとするのではなく、自動的に再レン​​ダリングされます。
あるコンポーネントから別のコンポーネントへの制御。 共有されている場合でも、データを切り離してAをコンポーネントAからレンダリングします。 fetchDataやhasInitializedなどのメソッドを含む単一のクラスを使用しました。後者はpromiseであり、前者は後者を解決します。
コンポーネントを直接結合すると、予期しない依存関係ツリーが作成され、コンポーネントが再利用できなくなり、vueがコンポーネントを正しく再レンダリングできるようになります。

または、グローバルスコープではなく、A、B、Cの親に直接イベントをemitて、BとCをレンダリングするかどうかを親に決定させます。

  <template>
    <a-component @rendered="showBandC = true" />
    <b-component v-if="showBandC" />
    <c-component v-if="showBandC" />
  </template>

この場合、BとCがレンダリングする前に実際にレンダリングする必要があるのはAについて何ですか。 created()メソッドに何かがある場合、それがjavascriptクラスを介してストアにデータを入力したりstoreモジュールを使用したりすることを妨げるものは何もありません。 しかし、明示的なユースケースの方が役立つでしょう。つまり、キャプチャできないユーザーストーリーのUXは何ですか?

アイデアは、次のフック関数に進む前に、Vueが内部的に非同期を尊重することです。

その部分は理にかなっていることは確かですが、なぜ例を複雑にする必要があるのか​​わかりません。なぜこのユーザーストーリーのようなことを言ってはいけないのでしょうか。

私のコンポーネントにはasync beforeMountとasync mounted両方がありますが、 beforeMountのコードが完了する前に、 mountedのコードが起動しています。 beforeMountが完了する前に、 mounted起動をブロックするにはどうすればよいですか?

これは元のリクエストのようなものなので、2番目の応答で出された質問はまだ関連していると思います: https :

とりあえず締めくくりますが、より具体的な理由/ユースケース/影響についてフォローアップしてください。

以前に実行されたライフサイクルフックをブロックする必要があるという実際の有効なユースケースはありますか、それともライフサイクルフックが同期するのは正しいですか。 これまでのところ、議論は本質的に哲学的でした(優れたアーキテクチャの議論が行う傾向があるように)が、実際の問題は、これを行う実際の正当な理由があるかどうかです。 フレームワークが非同期コードを待つことが合理的であることは一瞬疑いません。 それを行わなかった、またはコールバックを渡さなかった(またはコールバックを渡したがコールバックにコールバックを渡さなかった)他のN個のライブラリで正確な問題が発生しました。 ただし、非同期ライフサイクルフックを使用することは実際には合理的ですか、それとも「実行すべきではない」ことを実行しようとした結果の理由ですか?

つまり、 createdになっていないコンポーネントをunmountしようとするとどうなるか、すごい、それをまだ待つのは悪いことです。 または、 mountedになっていないdestroyingは、その機能の実装者をうらやましく思いません。

私はこれに本当に混乱しています。BとCをAに結合する代わりに、コードを移動して「AをA.jsにロード」してから、A.jsに「B.data」と「C.data」を更新させます。 。 そうすれば、何らかの理由でA.dataが変更された場合、他のコンポーネントは委任しようとするのではなく、自動的に再レン​​ダリングされます。

それは複雑さが増し、悪い習慣です。 ここに完全に書いてみてください。意味を見てみましょう。しかし、私にとっては、複雑さが大幅に増しただけです。

あるコンポーネントから別のコンポーネントへの制御。 共有されている場合でも、データを切り離してAをコンポーネントAからレンダリングします。 fetchDataやhasInitializedなどのメソッドを含む単一のクラスを使用しました。後者はpromiseであり、前者は後者を解決します。

これは現在、コンポーネントを結合しすぎています。 Aを除いて、これらが他のなしで機能することを望んでいます。

コンポーネントを直接結合すると、予期しない依存関係ツリーが作成され、コンポーネントが再利用できなくなり、vueがコンポーネントを正しく再レンダリングできるようになります。

実際、あなたは要点を見逃しています。これらは、それぞれが他に影響を与えることなく使用および維持できる拡張に緩く結合されています。 実際、 <component-x />外の親にコードを記述せずに、どこにでもそれらのいずれかを複数回ドロップできます。 v-ifはなく、その状態を管理するためのvuexなどはありません。

示すために、それらをAからBおよびCに結合しました。これをうまく分割するか、応答したコンポーネントの数を数えて、特定の期待数(この場合は2)に達したときに続行することができます。例:

 this.$root.$emit('thruster-mounted') // in B and C
// instead of 
 this.$root.$emit('thruster-1-mounted') // for B and 2 for C

// then count the responses and resolve once they are >= 2 in component A

とにかく、それがコンポーネントの依存関係の処理について述べた理由です。これは望ましいことであり、期待されていますが、複雑になるほど混乱するため、できるだけ複雑にしないで実行する必要があります。

または、グローバルスコープではなく、A、B、Cの親に直接イベントをemitて、BとCをレンダリングするかどうかを親に決定させます。

あなたがこれを言うつもりだったのは知っていましたが、これは望ましくありません。 これらのコンポーネントは他のものによって制御されるべきではないので、メインコンポーネントはその子供が何をするかをあまり気にせず、独立したままでなければならないことを強調しました。 アプリのどこにでも配置できるようにし、それでも同じことを機能させたいと思っています。 あなたがそこで言っていることをした瞬間、すべてがどのようにバラバラになるかを見てください。 しかし、私は文字通りDOMツリーのどこにでもコンポーネントを簡単に配置でき、すべてがうまく機能します。 私はこれの複数のコピーを持つことさえできます、そしてそれはまだ働きます。 ライフサイクルのasync ... awaitに感謝します。

  <template>
    <a-component @rendered="showBandC = true" />
    <b-component v-if="showBandC" />
    <c-component v-if="showBandC" />
  </template>

この場合、BとCがレンダリングする前に実際にレンダリングする必要があるのはAについて何ですか。

マウントする前に、各コンポーネントに固有の作業を実行してもらいたい。 ただし、すべてのコンポーネントは、他のすべてのコンポーネントがその作業を完了したときにのみレンダリングされます。 それがここでの話です。
状態管理とv-if使って頑張ってください。これは、 v-ifのvuex状態管理を作成する必要があります。 問題がわかりますか? 説明させてください:

  // component Z totally different from foo, so we can't make this a component for reuse
  <template>
    <a-component @rendered="showBandC = true" />
    <c-component v-if="showBandC" />
  </template>
 ...
computed: {
showBandB() { ...vuex ...,
showBandC() { ...vuex ...,
}
  // component Foo totally unique, probably has other things it does
  <template>
    <b-component v-if="showBandC" />
    <c-component v-if="showBandC" />
  </template>
 ...
computed: {
// ok you could mixin this, fair, but complex nevertheless
showBandB() { ...vuex ...,
showBandC() { ...vuex ...,
}

.....そしてすっごく

次のように、親で何もせずにコンポーネントを使用する代わりに、次のようにします。

  // component Z
  <template>
    <a-component />
    <b-component />
  </template>
  // component Foo
  <template>
    <b-component  />
    <c-component />
  </template>

...なお

created()メソッドに何かがある場合、それがjavascriptクラスを介してストアにデータを入力したりstoreモジュールを使用したりすることを妨げるものは何もありません。 しかし、明示的なユースケースの方が役立つでしょう。つまり、キャプチャできないユーザーストーリーのUXは何ですか?

どこにでも散らばっている状態管理について私が言ったことを覚えていますか? これらのコンポーネントを管理するということは、他の場所で多くのことを管理することを意味することを望んでいません。これは、私が今行ったことではなく、非常に複雑です。 その上、それは私がこれにしたいことをしません。 各コンポーネントが、ほとんど複雑さを伴わずに実行することになっていることを完了したときにのみマウントします。

アイデアは、次のフック関数に進む前に、Vueが内部的に非同期を尊重することです。

その部分は理にかなっていることは確かですが、なぜ例を複雑にする必要があるのか​​わかりません。なぜこのユーザーストーリーのようなことを言ってはいけないのでしょうか。

私のコンポーネントにはasync beforeMountとasync mounted両方がありますが、 beforeMountのコードが完了する前に、 mountedのコードが起動しています。 beforeMountが完了する前に、 mounted起動をブロックするにはどうすればよいですか?

重要なのは、これらのコンポーネントのいずれかがレンダリングされる前に物事が発生し、コンポーネント自体の外部にあまり多くの入力をしなくても使用できるようにすることです。 これは、私たちが作成しているアプリが利用可能であれば、もっとうまくやれたはずだと私が気付いた実際のことです。 私は結局、多くのミックスイン、vuex、そしてどこにでも(ミックスインを使用して)強く結合された親を持つコードを書くことになりました。これが欠落しているため、コンポーネントが使用されました。 これは複雑な話ではありません。実際に何が起こったのかを簡単に説明しています。 UIの設計と保守の方法を再考する必要がありました。 視覚的には少し面白くなくなり、コード的にはかなり複雑になりました。

この単純なセットアップに導入した、その小さな非同期によって解決された複雑なものがいくつあるかわかりますか...ライフサイクルの機能を待ちますか?

@wparad

つまり、作成が完了していないコンポーネントをアンマウントしようとするとどうなるか、すごい、それをまだ待っているのは悪いことです。 または、マウントが完了していないものを破棄しても、その機能の実装者はうらやましくありません。

これはどこです:

...達成するには、アーキテクチャの根本的な再考/書き直しが必要であり、ライフサイクルフックの同期性に依存する多くのロジックを壊す可能性があります...

...あなたが言及していたと私が信じる部分。 これらのエッジケースを処理する方法が必要であり、おそらくこれがもたらす以上の方法が必要です。 言い換えれば、私たちの意図はアプリをクラッシュさせることなく機能する必要があります。

これらすべての場合において、失敗する可能性のあるほとんどの非同期操作と同様に、タイムアウトを使用して待機をチェックまたは中止します。

しかし、私が注意深く提示した例を見ると、私が何を意味しているのかがわかります。 これは、どこにも多くのコードを書かなくても、多くのことを解決できたはずです。 実際、これが可能であれば、私たちのアプリははるかに小さく、デフラグされ、コードベースを把握しやすいので、はるかに優れていた可能性があります。
これらの種類の機能についてのことは、障害にぶつかったときにのみそれらの重要性がわかるということです。 私が最初にこのページにアクセスしたのは、私が今挙げたまさにこの例について多くの回避策を考えたときです。 私は助けを求めに来ていませんでした。Vueで利用できないことに気付いたので、機能リクエストを提出することでした。

このページは役に立ちましたか?
0 / 5 - 0 評価