Vue: Tunggu kait siklus hidup komponen async

Dibuat pada 8 Des 2017  ·  51Komentar  ·  Sumber: vuejs/vue

Masalah apa yang dipecahkan oleh fitur ini?

Jika pengguna perlu mengimplementasikan hook siklus hidup yang bergantung pada operasi async, vue harus menghormati sifat async dari hook yang diimplementasikan dan menunggunya di vue land.

Seperti apa tampilan API yang diusulkan?

API tidak berubah; hanya cara kerjanya sekarang dengan menunggu kait async.

Komentar yang paling membantu

Ini adalah kode aktual yang ingin saya tunggu:

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

Yang akan menjadi bagian dari komponen UserPage .

Semua 51 komentar

Jadi kamu mau

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

menampilkan

mounted

?

Saat membuat permintaan fitur, harap tambahkan kasus penggunaan dunia nyata agar permintaan tersebut layak untuk diterapkan.

Meskipun ini secara teoritis adalah ide yang keren, ini membutuhkan pemikiran ulang/penulisan ulang arsitektur yang mendasar untuk dicapai, dan berpotensi dapat mematahkan banyak logika yang bergantung pada sifat sinkron dari kait siklus hidup. Jadi manfaatnya harus substansial untuk membenarkan perubahan itu - jika tidak, ini hanya dapat dipertimbangkan ketika kami berencana untuk melakukan peningkatan penuh, yang tidak mungkin terjadi segera.

Penutupan untuk saat ini, tetapi jangan ragu untuk menindaklanjuti dengan alasan / kasus penggunaan / implikasi yang lebih konkret.

@posva Dimengerti -- saya minta maaf. Kasus penggunaan saya yang sebenarnya adalah di mana saya memiliki komponen UserPage yang menerima user_id dari parameter rute halaman (melalui this.$route.params ), kemudian mengambil data pengguna aktual dari database di server menggunakan perintah seperti:
this.user = await client.get({type: 'user', id: this.$route.params.id})
di mana this.user merujuk ke bidang user di bagian data dari komponen UserPage .

Idealnya, saya ingin baris kode tersebut dieksekusi setelah komponen dibuat (sehingga this.$route.params tersedia) tetapi sebelum komponen benar-benar di-mount sehingga dalam template saya, saya dapat menggunakan user interpolasi tanpa mendapatkan kesalahan tentang nilai yang tidak ditentukan.

@yyx990803
Saya mungkin pemula di sini, tetapi bukankah satu-satunya perubahan adalah menambahkan kata kunci await sebelum panggilan untuk kait siklus hidup seperti mounted , dll, di Vue land?

Ini adalah kode aktual yang ingin saya tunggu:

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

Yang akan menjadi bagian dari komponen UserPage .

Jangan khawatir! Saya membayangkan kasus penggunaan itu. Lebih baik untuk menanganinya seperti yang dijelaskan dalam dokumen vue-router karena membuka berbagai cara untuk menampilkan status pemuatan. Anda sudah bisa menunggu data ada di sana sebelum merender komponen btw.

Oke itu masuk akal. Namun, sekarang bagaimana jika saya memiliki komponen pengguna yang merupakan versi halaman pengguna yang dipreteli (misalnya, seperti komponen yang muncul saat Anda mengarahkan kursor ke nama pengguna di facebook dan "mengintip" ke profil mereka), maka router tidak terlibat di sini dan id akan diteruskan sebagai properti ke komponen.

Mengambil gambaran besar di sini, fungsi dalam JavaScript sekarang dapat menjadi sinkron atau asinkron, dan kait siklus hidup menjadi fungsi, dan cara kita menganggapnya sebagai fungsi, harus mendukung asinkronitas (seperti yang ditunjukkan oleh kasus penggunaan saya dan "jangkauan" intuitif untuk pendekatan yang saya gunakan di sini).

Anda memiliki banyak cara untuk melakukannya. Yang paling sederhana adalah menggunakan variabel yang dimulai sebagai nol, mengambil data dan mengaturnya, mengaktifkan komponen aktual (karena v-if). Versi yang lebih eksotis adalah fungsi yang menyelesaikan komponen dan menggunakan <component :is="myDynamicComp"/>
Tapi tolong, jangan membajak masalah menjadi pertanyaan gunakan forum atau perselisihan untuk itu

Tidak, saya benar-benar tidak ingin bantuan dengan kode! Sebenarnya saya sudah menerapkan solusi yang sangat mirip dengan saran Anda. Apa yang saya coba katakan adalah jauh lebih intuitif untuk hanya menggunakan fitur async JS.

Bagian yang tidak saya sadari adalah bahwa kode asinkron dan sinkron pada dasarnya berbeda, sehingga kode sinkron tidak dapat dipaksa untuk mematuhi kode asinkron tanpa secara mendasar mengubah dirinya menjadi kode asinkron. yyx990803 melihatnya segera tetapi saya butuh beberapa waktu untuk memahami komentarnya sepenuhnya. Terima kasih untuk waktu kalian dan maaf jika ada miskomunikasi di pihak saya selama ini.

Saya memiliki beberapa kasus penggunaan di sini dan ingin mendapatkan beberapa saran dan metode penyelesaian.

MainPage.vue adalah wadah utama saya. Saya memanggil ajax "/init" di beforeCreate untuk mendapatkan info pengguna dan kemudian berkomitmen ke Vuex.store.
Content.vue adalah anak di dalam MainPage.vue . Saya ingin memanggil panggilan api yang berbeda pada tahap mounted sesuai dengan peran pengguna yang berasal dari Vuex.store.

Jika panggilan siklus hidup dalam aliran async/menunggu, itu akan mengikuti perintah
Parent beforeCreate -> Parent create -> Child beforeCreate -> Child create -> Child mount .... (Jika saya mengerti benar tentang siklus hidup komponen).

Tetapi saat ini saya tidak bisa mendapatkan info pengguna di Content.vue , bagaimana saya bisa mendapatkan solusinya sekarang?
Saya ingin tetap memanggil api "/ init" di dalam MainPage.vue karena digunakan di banyak halaman (wadah di Vue-Router).

memposting pertanyaan di stackoverflow

Terima kasih

solusi peretasan untuk apa yang layak:

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


Kemungkinan solusi yang lebih "datar":

{
    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
        }
    }
}

Apakah ini belum apa-apa?

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

Bekerja untuk saya (seperti yang disebutkan @fifman ).

@breaddams Ya, tentu saja. Fungsi _di dalam_ metode created akan ditunggu - namun fungsi created atau mounted itu sendiri tidak.

Jadi instance Vue akan memanggil created dan langsung mounted sebelum proses yang berjalan lama di created selesai

Ah , @darren-dev buruk saya - kasus penggunaan berbeda di pihak saya, tetapi saya melihat masalahnya sekarang terima kasih telah mengklarifikasi.

@breaddams Tidak ada masalah sama sekali - kita semua di sini untuk kasus kita sendiri, senang saya bisa mengklarifikasi!

Kait siklus hidup Async dapat menjadi implementasi yang baik di versi utama berikutnya

Menurut saya, mengizinkan dukungan async untuk metode siklus hidup akan mendorong praktik UX yang buruk secara default. Bagaimana? Fungsi asinkron digunakan untuk permintaan yang tidak dapat diselesaikan dengan segera (mis. permintaan yang sudah berjalan lama atau jaringan). Memaksa Vue untuk menunda pembuatan atau pemasangan atau metode siklus hidup lainnya untuk menunggu permintaan jaringan Anda atau proses asinkron yang berjalan lama akan berdampak pada pengguna dengan cara yang nyata. Bayangkan seorang pengguna datang ke situs Anda dan kemudian harus menunggu selama 4 detik dengan layar kosong sementara komponen menunggu koneksi seluler pengguna untuk menyelesaikan permintaan jaringan Anda. Dan ini tidak hanya berdampak negatif pada pengguna tetapi Anda juga mengorbankan kendali Anda atas situasi - tidak ada yang dapat Anda lakukan sebagai pengembang untuk membuat waktu muat yang dirasakan pengguna lebih cepat, atau menunjukkan indikator kemajuan yang pasti atau tidak pasti. Jadi dengan membangun kemampuan ini ke dalam Vue, Anda tidak membuat web menjadi tempat yang lebih baik; Anda mengaktifkan praktik buruk.

Jauh lebih baik untuk merencanakan dan mendesain kasing asinkron sejak awal: mulai proses asinkron Anda di created atau mounted atau di mana pun, lalu buat komponen Anda memiliki struktur kerangka atau paling buruk pemintal saat Anda menunggu API Anda mengembalikan izin pengguna. UX yang jauh lebih baik dan Anda tidak mengorbankan kontrol apa pun. Dan Vue tidak perlu menambahkan kode untuk menangani fungsi siklus hidup asinkron, menjaga bundel lebih kecil. Menang menang.

@seanfisher Anda menaikkan poin yang valid. Secara arsitektur, mendesain di sekitar rangkaian peristiwa yang tidak sinkron harus ditangani oleh pengembang - karena itulah satu-satunya cara untuk menggambarkan pesan dengan benar.

Penafian : Berikut ini ditulis dengan ide pembuatan halaman dalam pikiran. Pasti ada kasus penggunaan yang valid di mana argumen saya tidak valid.


Namun, mendikte pola desain pengembang tidak boleh diserahkan kepada kerangka kerja yang Anda gunakan. Argumen saya adalah jika Anda tidak menunggu fase selesai - lalu mengapa memiliki fase yang berbeda? Mengapa memiliki panggung yang dibuat, lalu dipasang? Jika semuanya pada dasarnya terjadi sekaligus, maka mengabaikan tahap yang dibuat sama sekali tidak masalah.

Secara harfiah, satu-satunya waktu saya (Sejak awal Vue) terhubung ke dibuat adalah ketika saya harus menyuntikkan sesuatu yang perlu diandalkan vue - itu tidak ada hubungannya dengan pengaturan atau tata letak halaman saya. Namun, saya harus menunggu tugas async (pendek) untuk dijalankan yang akan jauh lebih baik _sebelum_ halaman dirender (Seperti menghubungkan ke metode otentikasi Firebase). Setelah itu di buat, lalu menunggu sampai selesai sebelum dipasang akan mengurangi kebutuhan penyelesaian solusi peretasan.

Ingat, argumen saya adalah bahwa Vue seharusnya tidak memberi tahu saya bahwa saya salah berkembang. Seharusnya hanya menyediakan fungsionalitas yang diinginkan.

Namun, mendikte pola desain pengembang tidak boleh diserahkan kepada kerangka kerja yang Anda gunakan.

Um....Kerangka dibuat untuk secara khusus membatasi atau memandu atau "membingkai" pengembang ke dalam pola dan praktik desain tertentu. Itu tujuan utama mereka. Kerangka kerja apa pun yang baik akan menawarkan API cerdas, yang secara tepat menawarkan cara yang jelas dan jelas untuk bekerja dengan kerangka kerja tersebut, namun juga akan membatasi.

Ya, adalah paradoks bahwa kerangka kerja menawarkan kemampuan tertentu, namun juga membatasi pengembang pada saat yang sama untuk praktik desain tertentu. Di situlah pendapat dalam Kerangka dapat membantu atau menyakitinya. Sulit untuk menemukan keseimbangan yang tepat dan saya pikir Vue atau lebih tepatnya Evan dan tim pengembang Vue telah melakukan dan melakukan pekerjaan yang baik untuk membuat keputusan ini.

Scott

Saya tidak akan pernah berpendapat bahwa kerangka kerja yang dirancang dengan baik harus diperluas dengan pola desain yang sama, tetapi argumen saya adalah bahwa kerangka kerja tidak dapat mendiktenya. Anda benar, tetapi saya mengatakan bahwa tidak peduli seberapa bagus kerangka kerjanya, pengembang akhir harus tetap terbuka untuk melakukan apa pun yang mereka inginkan.

Tetapi Anda belum menyentuh argumen _actual_ untuk membuat acara yang dibuat dan dipasang tidak sinkron - Anda baru saja menambahkan pendapat Anda (yang tidak salah) pada pendapat saya, yang umumnya mengarah pada penggelinciran besar.

Saya tidak akan pernah berpendapat bahwa kerangka kerja yang dirancang dengan baik harus diperluas dengan pola desain yang sama, tetapi argumen saya adalah bahwa kerangka kerja tidak dapat mendiktenya.

Maaf, tapi ini tidak masuk akal bagiku. Tolong tunjukkan saya satu kerangka kerja yang tidak menentukan bagaimana itu harus diperpanjang.

Saya pikir ucapan saya "Evan and Co membuat penilaian yang baik" akan menunjukkan pendapat saya. Tapi, agar lebih jelas. Kait siklus hidup yang dipasang dan dibuat tidak perlu bekerja secara asinkron atau lebih tepatnya, fakta bahwa mereka bekerja secara sinkron membantu dengan penalaran tentang logika aplikasi. Setiap "menunggu" perlu diperhitungkan di UI dan kode asinkron masih dapat dijalankan di setiap kait. Kita dapat berdebat tentang kebutuhan kait beforeMount dan mount. Tapi, mungkin ada satu atau dua hal yang mungkin Anda perlukan di mount, misalnya, yang belum bisa Anda akses saat dibuat, seperti fungsi render yang dikompilasi.

Scott

Jika Vue memiliki pendapat dengan satu atau lain cara tentang kait siklus hidup async, itu seharusnya tidak menjadi masalah spekulasi. Tidak perlu berspekulasi kapan standar, API, panduan, dan praktik terbaik yang diadopsi, disediakan, atau direkomendasikan Vue tersedia untuk dibaca semua orang.

Dalam balasan asli Evan, kait siklus hidup async tidak ada dalam API standar bukan karena itu merupakan ide yang buruk, tetapi karena manfaatnya tidak cukup besar untuk membenarkan biaya implementasi.

Untuk pendapat bahwa itu adalah praktik yang buruk untuk membuat pengguna menunggu async created atau kait siklus hidup lainnya tanpa indikator bahwa sesuatu sedang terjadi, argumen dapat dibuat bahwa Vue, setelah mendukung kait async, sekarang mungkin menyediakan sesuatu yang dapat disebut "templat fase" yang juga akan menyelesaikan masalah (dan yang dapat dengan mudah diterapkan).

Untuk pendapat bahwa itu adalah praktik yang buruk untuk membuat pengguna menunggu async dibuat atau kait siklus hidup lainnya tanpa indikator bahwa sesuatu sedang terjadi,

Apakah ini benar-benar masalah?

Scott

Inilah masalah yang saya alami -- dan mungkin seseorang dapat menyarankan bagaimana saya HARUS melakukan ini karena ini tampak bermasalah.

Aplikasi Vue kami (agak besar) menggunakan Vuex secara ekstensif. Dalam beberapa komponen Vue kami di siklus hidup create() kami mengatur melalui store.dispatch() beberapa item di toko (jelas). Namun, seperti yang menjadi perhatian saya -- store.dispatch() SELALU mengembalikan janji .. bahkan jika logika dan fungsi yang mendasarinya TIDAK asinkron. Jadi saya memasukkan async create() { menunggu store.dispatch('foo/action') } tetapi seperti yang dicatat bahwa sebenarnya gagal ..

Saya juga menggunakan TypeScript dan mengeluh agak pahit ketika saya tidak menunggu / .then store.dispatch() memanggil .. memiliki janji "mengambang"..

Jadi apa cara terbaik untuk menggunakan Vuex store.dispatch() dalam siklus hidup ketika kita tidak dapat menyinkronkannya?

Bersulang!!

Semua diskusi lain tentang opini spesifik vue, dan apakah kerangka kerja harus mengesampingkan opini, akan bermanfaat untuk mendokumentasikan perilaku ini dengan lebih jelas.

Saya melihat solusi "lebih datar" mounted() kembali. Dalam solusi itu, created() dan mounted() adalah async, jadi Vue akan memanggil masing-masing dari mereka dan mereka akan segera kembali, dengan hal-hal async terjadi di latar belakang. Sebenarnya saya tidak yakin bagaimana itu lebih baik daripada hanya menghilangkan createdPromise dan hanya melakukan semua pekerjaan async baik created() atau mounted() , seperti:

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

Bagaimanapun, my_data_member akan diisi "nanti" ketika XHR selesai, lama setelah mounted() mengembalikan Janjinya, bukan?

Anda juga dapat mencoba menggunakan v-if pada komponen root <div id="app"/> dan memicunya saat pemuatan data Anda selesai. Saya, misalnya, menggunakannya untuk token penyegaran.

Ini adalah fitur keren untuk dimiliki dan memiliki banyak kasus penggunaan. Untuk kasus penggunaan saya, saya perlu memuat properti API tertentu sebelum render komponen yang sebenarnya. Namun, saya tidak merasa bahwa async dalam kait siklus hidup adalah solusi yang ideal.

Saat ini semua orang menyebutkan di sini skenario sempurna di mana fungsi async berjalan dengan lancar. Tapi katakanlah misalnya jika koneksi pengguna lambat atau tertinggal dan kami menunggu komponen dipasang setelah respons API, maka seluruh siklus hidup komponen didistribusikan. Kami tidak akan dapat menampilkan informasi pemuatan kepada pengguna. Atau jauh lebih buruk, jika waktu API habis atau mengembalikan kesalahan, aplikasi akan hang tanpa pemasangan.

Meskipun ini adalah fitur yang keren untuk dimiliki, saya akan menyarankan untuk ditangani oleh aplikasi daripada kerangka kerja karena implementasi logika domain memiliki lebih banyak wawasan tentang logika yang mendasarinya daripada kerangka kerja sehingga menciptakan lebih sedikit efek samping.

+1 untuk fitur ini.
Saya memiliki mixin yang digunakan oleh berbagai komponen, mixin mengambil data dari database di hook yang dipasang.
Komponen harus bekerja dengan data yang diambil oleh mixin juga di hook yang terpasang.
Seperti sekarang, saya harus menerapkan panggilan balik untuk dipanggil ketika mixin selesai memuat data dan membuang kait yang terpasang di komponen.
Ini berfungsi tetapi akan lebih cantik jika kait yang dipasang menangani janji.

@cederron murni karena minat, mengapa Anda tidak dapat mengunduh data di komponen induk dan meneruskannya sebagai penyangga? gunakan v-if untuk menampilkan indikator pemuatan saat data dimuat dan ketika data muncul, Anda dapat menampilkan komponen, dan ketika dibuat, ia akan memiliki semua data yang dibutuhkan.

Menghindari komponen mewakili dua status berbeda yang tidak terkait ('tidak ada data yang dimuat, menunggu' dan 'data telah dimuat, Anda dapat memanipulasinya')

Jika Anda perlu menggunakan kembali logika di beberapa tempat, bahkan mungkin memindahkan logika unduhan ke Vuex, agak masuk akal karena mengunduh data akan dilakukan dalam tindakan Vuex daripada komponen.

@ReinisV Saya pikir saya terlalu menyederhanakan kasus saya, komponen membuat data baru dari data yang diambil oleh kait yang dipasang di mixin, dan tampilan komponen diikat ke data baru ini.
Jadi, mixin harus mengambil data dari database > komponen membuat data darinya > sekarang komponen ditampilkan

AFAIK ini tidak akan berfungsi:

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 akan menjadi nol di kait pemasangan komponen.

Saat ini saya menjalankan panggilan balik ketika mixin mengambil data tetapi akan lebih cantik untuk membuat fungsi mount async.

Tidak bisa mengatakan banyak tentang vuex karena saya tidak menggunakannya

Saya benar-benar ingin mengulangi apa yang disebutkan @seanfisher di sini. Memiliki vue wait pada komponen yang telah ditandai sebagai async tidak hanya menyebabkan masalah bagi pengguna, pola penggunaan async/await untuk memulai pencarian data ada di mana-mana. Itu akan memaksa secara eksplisit mengonversi kode dalam kait siklus hidup ini menjadi janji yang tidak ditunggu untuk secara eksplisit menghindari pemblokiran vue. Dalam beberapa kasus mungkin bagus, dan jika sebuah fitur akan diperkenalkan, saya harus menyarankan menjalankan dua siklus hidup pada saat yang sama, yang saat ini menangani eksekusi kait komponen dan yang menunggu eksekusi tersebut untuk panggilan balik global.

Tapi saya benar-benar akan kecewa untuk benar-benar menulis ulang setiap kait siklus hidup saya untuk menghindari pemblokiran vue, async/await jauh lebih bersih, jadi kami tidak menggunakan janji. Mengubah ini dengan cara yang tidak kompatibel ke belakang akan mengubah lubang kesuksesan (siklus hidup komponen yang tidak ditunggu) menjadi lubang kegagalan.

Jauh lebih baik untuk merencanakan dan mendesain kasing asinkron sejak awal: mulai proses asinkron Anda di created atau mounted atau di mana pun, lalu buat komponen Anda memiliki struktur kerangka atau paling buruk pemintal saat Anda menunggu API Anda mengembalikan izin pengguna. UX yang jauh lebih baik dan Anda tidak mengorbankan kontrol apa pun. Dan Vue tidak perlu menambahkan kode untuk menangani fungsi siklus hidup asinkron, menjaga bundel lebih kecil. Menang menang.

@seanfisher Terima kasih, ini sangat membantu!

Mengapa tidak menggunakan komponen asinkron sebagai gantinya, yang akan dirender hanya ketika panggilan asinkron telah kembali?
info lebih lanjut tentang API di sini
https://vuejs.org/v2/guide/components-dynamic-async.html#Async -Komponen

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')
})

sementara sebagian besar solusi ini tampak baik-baik saja, saya pikir ini adalah salah satu bagian utama Vue yang hilang yang membuatnya sangat intuitif. Saya pikir Vue 3 perlu menerapkan ini karena kami telah sampai pada titik di mana menggunakan async menunggu sekarang menjadi hal sehari-hari. JADI TOLONG @yyx990803 Anda, mari kita miliki di Vue 3. PLEEEEEEEASE. Seluruh arsitektur VUE dibuat tanpa asumsi untuk kasus ini dan sebagian besar hal yang diposting orang di sini hanyalah solusi dan peretasan. Saya pikir kait harus benar-benar menghormati fungsi async dan juga mengharapkan nilai pengembalian juga yang kemudian diteruskan ke fungsi kait berikutnya.

Saya akan memperbaiki kode saya melihat ini tidak dihormati, tetapi kode jelek akan keluar darinya karena itu akan menjadi peretasan.

Menurut saya, mengizinkan dukungan async untuk metode siklus hidup akan mendorong praktik UX yang buruk secara default. Bagaimana? Fungsi asinkron digunakan untuk permintaan yang tidak dapat diselesaikan dengan segera (mis. permintaan yang sudah berjalan lama atau jaringan). Memaksa Vue untuk menunda pembuatan atau pemasangan atau metode siklus hidup lainnya untuk menunggu permintaan jaringan Anda atau proses asinkron yang berjalan lama akan berdampak pada pengguna dengan cara yang nyata. Bayangkan seorang pengguna datang ke situs Anda dan kemudian harus menunggu selama 4 detik dengan layar kosong sementara komponen menunggu koneksi seluler pengguna untuk menyelesaikan permintaan jaringan Anda. Dan ini tidak hanya berdampak negatif pada pengguna tetapi Anda juga mengorbankan kendali Anda atas situasi - tidak ada yang dapat Anda lakukan sebagai pengembang untuk membuat waktu muat yang dirasakan pengguna lebih cepat, atau menunjukkan indikator kemajuan yang pasti atau tidak pasti. Jadi dengan membangun kemampuan ini ke dalam Vue, Anda tidak membuat web menjadi tempat yang lebih baik; Anda mengaktifkan praktik buruk.

Jauh lebih baik untuk merencanakan dan mendesain kasing asinkron sejak awal: mulai proses asinkron Anda di created atau mounted atau di mana pun, lalu buat komponen Anda memiliki struktur kerangka atau paling buruk pemintal saat Anda menunggu API Anda mengembalikan izin pengguna. UX yang jauh lebih baik dan Anda tidak mengorbankan kontrol apa pun. Dan Vue tidak perlu menambahkan kode untuk menangani fungsi siklus hidup asinkron, menjaga bundel lebih kecil. Menang menang.

Satu pendapat dari ribuan. Hanya karena Anda tidak dapat membayangkan skenario di mana rendering komponen yang tertunda dapat hidup berdampingan dengan pengalaman pengguna yang positif, bukan berarti itu tidak ada.

Jika kerangka kerja melawan pengembang, pengembang akan menemukan kerangka kerja lain.

@robob4him

Satu pendapat dari ribuan. Hanya karena Anda tidak dapat membayangkan skenario di mana rendering komponen yang tertunda dapat hidup berdampingan dengan pengalaman pengguna yang positif, bukan berarti itu tidak ada.

Jika kerangka kerja melawan pengembang, pengembang akan menemukan kerangka kerja lain

Anda benar sekali, tetapi tidak ada yang Anda bagikan di sini adalah argumen yang valid untuk menyelesaikan masalah dengan satu atau lain cara. Anda telah memperkenalkan taktik menakut-nakuti untuk memaksa komunitas mengembangkan fitur. Bukan kelanjutan percakapan yang konstruktif.

@wparad , ini benar-benar taktik menakut-nakuti, tetapi itu tidak akan memaksa siapa pun untuk melakukan apa pun. Mengemukakan argumen bahwa fitur mendukung kebiasaan buruk atau anti-pola atau akan merusak komunitas pengembang yang lebih besar juga merupakan taktik menakut-nakuti.

Setengah fitur dari kerangka kerja/bahasa apa pun berbahaya bagi pengembang; metode publik dapat diperpanjang, Vue mendorong akses ke elemen ($el), dll. Kerangka kerja menyediakan hal-hal ini karena pada akhirnya pengembang perlu menyelesaikan pekerjaan.

Permintaan fitur ini berumur satu tahun. Orang-orang harus memahami bahwa alasannya sebenarnya bukan karena itu akan menyebabkan praktik buruk dan mereka juga tidak boleh menganggap rendering tertunda sebagai praktik buruk.

Saya perlu menggunakan requirejs dengan vue. Bukannya saya suka requirejs tetapi karena saya ingin menggunakan vue dengan LMS open source yang memiliki semua modulnya sebagai modul AMD. Akan sangat bagus jika saya bisa memuat semua lib yang saya butuhkan di hook beforeCreate. Alternatif bagi saya saat ini adalah memuatnya di luar vue dan kemudian meneruskannya ke tempat yang lebih berantakan.

Menurut saya, mengizinkan dukungan async untuk metode siklus hidup akan mendorong praktik UX yang buruk secara default. Bagaimana? Fungsi asinkron digunakan untuk permintaan yang tidak dapat diselesaikan dengan segera (mis. permintaan yang sudah berjalan lama atau jaringan). Memaksa Vue untuk menunda pembuatan atau pemasangan atau metode siklus hidup lainnya untuk menunggu permintaan jaringan Anda atau proses asinkron yang berjalan lama akan berdampak pada pengguna dengan cara yang nyata. Bayangkan seorang pengguna datang ke situs Anda dan kemudian harus menunggu selama 4 detik dengan layar kosong sementara komponen menunggu koneksi seluler pengguna untuk menyelesaikan permintaan jaringan Anda. Dan ini tidak hanya berdampak negatif pada pengguna tetapi Anda juga mengorbankan kendali Anda atas situasi - tidak ada yang dapat Anda lakukan sebagai pengembang untuk membuat waktu muat yang dirasakan pengguna lebih cepat, atau menunjukkan indikator kemajuan yang pasti atau tidak pasti. Jadi dengan membangun kemampuan ini ke dalam Vue, Anda tidak membuat web menjadi tempat yang lebih baik; Anda mengaktifkan praktik buruk.

Jauh lebih baik untuk merencanakan dan mendesain kasing asinkron sejak awal: mulai proses asinkron Anda di created atau mounted atau di mana pun, lalu buat komponen Anda memiliki struktur kerangka atau paling buruk pemintal saat Anda menunggu API Anda mengembalikan izin pengguna. UX yang jauh lebih baik dan Anda tidak mengorbankan kontrol apa pun. Dan Vue tidak perlu menambahkan kode untuk menangani fungsi siklus hidup asinkron, menjaga bundel lebih kecil. Menang menang.

Apa yang Anda katakan adalah seperti menambahkan fitur v-if/v-clock/v-show akan mendorong praktik buruk sehingga kami lebih baik membodohi kerangka kerja dengan menghapus fitur tersebut. Kemudian gunakan beberapa pendekatan berbelit-belit untuk melakukan hal yang sama sehingga Vue lebih kecil karena tidak menempatkan 3 arahan tersebut. Pengembang pertama tidak bodoh. 2nd-proofing framework pada gilirannya membatasi kegunaannya karena Anda membatasi apa yang dapat dilakukan berdasarkan "orang bodoh" yang nyata. Mengapa seseorang menaruh v-if untuk seluruh situs web mereka untuk memblokirnya melalui operasi asinkron yang membiarkan seluruh layar kosong?

Saya pikir Anda mengabaikan fakta bahwa sebagian besar kasus penggunaan bahkan mungkin tidak dengan halaman kosong. Mereka disebut komponen karena suatu alasan. Kasus di mana saya pribadi ingin menggunakan ini adalah di mana sesuatu sudah ada di layar melakukan sesuatu yang lain. Ini mungkin komponen yang diblokir oleh v-if misalnya dan dipicu ketika sesuatu berubah. Namun, dalam proses rendering untuk pertama kalinya, async functions dll perlu diperhatikan saat komponen melakukan booting. Saya menyerempet seluruh dokumentasi Vue mencari ini dan akhirnya melakukannya dengan solusi yang sangat tidak terlalu bagus seperti contoh peretasan di atas.

Yang membuat saya khawatir adalah seseorang/bahkan kemudian saya yang memelihara kodenya. Ini seperti neraka panggilan balik Janji vs Async ... Tunggu.

Sebenarnya saya melihatnya meningkatkan fleksibilitas dan kemampuan kontrol kerangka kerja dengan cara yang mudah diikuti. Lihat saja peretasan di atas untuk melihat apa yang saya maksud. Pengembang melakukan semua itu hanya untuk mengisi celah pernyataan async mounted () { await... } misalnya. Jika Anda tidak ingin menggunakan fitur tersebut, Anda hanya tidak mendefinisikan fungsi sebagai async atau bahkan menggunakan await sama sekali.

Sebenarnya seseorang yang benar-benar akan menggunakan kait siklus hidup async mounted kemungkinan besar akan memahami apa yang mereka lakukan dan mengapa mereka akan melakukannya, dan kemungkinan besar TIDAK akan membuat praktik buruk yang Anda khawatirkan.

@emahuni , saya tidak berpikir ada yang akan tidak setuju dengan harapan yang Anda bagikan, tetapi saya pikir ada nuansa, yang ditinggalkan. Mari kita asumsikan bahwa async mounted atau async created menunda komponen untuk dirender. Apa yang dilakukan orang tua dalam kasus ini? Melakukannya:

  • blok juga
  • asumsikan bahwa komponen tersebut dimaksudkan untuk menghapus DOM v-if sampai selesai memuat
  • asumsikan bahwa komponen tersebut dimaksudkan untuk disembunyikan hingga pemuatan selesai
  • Tampilkan elemen sementara di tempatnya?

Meskipun saya setuju bahwa harapan di sekitar komponen yang dimuat secara dinamis konsisten, perilaku untuk induk menurut saya tidak demikian. Dalam kasus ini, IMO akan mengekspos implementasi anak kepada orang tua dan memaksa orang tua untuk mencari tahu apa yang harus dilakukan dengan komponen dinamis itu. Alih-alih bagaimana data dimuat dan status komponen anak harus terserah pada anak. Jika memuat async maka perlu beberapa cara untuk menjelaskan kepada Vue apa yang harus dirender di tempatnya (atau tidak dirender). Cara terbaik untuk menanganinya adalah bagaimana kerangka kerja sudah bekerja, daripada memperkenalkan kompleksitas baru.

Selanjutnya, saya tidak sepenuhnya mengikuti argumen Anda:

Apa yang Anda katakan seperti menambahkan fitur v-if/v-clock/v-show akan mendorong praktik buruk sehingga kami lebih baik membodohi kerangka kerja dengan menghapus fitur-fitur itu

Sementara dalam kasus ini, kita dapat dengan jelas melihat bahwa memperkenalkan komponen async yang menunggu pemasangan atau dibuat akan menyebabkan praktik buruk, tidak jelas apakah hal ini terjadi. Kedua, menimbulkan pertanyaan, bahkan jika itu memang menyebabkan praktik buruk, kita harus memilih untuk memperbaikinya , daripada menggunakannya sebagai pembenaran untuk membuat praktik buruk baru. Jika Anda mengetahui praktik buruk yang dibuat oleh v-if , dll... Saya mengundang Anda untuk membagikan secara eksplisit (dalam edisi lain tentu saja) apa masalahnya, daripada mencoba menggunakannya sebagai pembenaran untuk diskusi yang berbeda.

@emahuni , saya tidak berpikir ada yang akan tidak setuju dengan harapan yang Anda bagikan, tetapi saya pikir ada nuansa, yang ditinggalkan. Mari kita asumsikan bahwa async mounted atau async created menunda komponen untuk dirender. Apa yang dilakukan orang tua dalam kasus ini? Melakukannya:

  • blok juga

Orang tua dapat melanjutkan dan membuat tanpa menunggu anak, mengapa harus? Itu bisa langsung berjalan dan menjalankan updated setelah anak merender.

  • asumsikan bahwa komponen tersebut dimaksudkan untuk menghapus DOM v-if sampai selesai memuat

Saya tidak yakin saya mendapatkan ini ... tetapi jawabannya tidak, kami tidak menganggap itu akan dihapus, itu hanya perlu melakukan sesuatu selama mount yang harus memblokir mount selama waktu itu. Ada banyak kasus penggunaan yang dibaca di atas untuk itu.

  • asumsikan bahwa komponen tersebut dimaksudkan untuk disembunyikan hingga pemuatan selesai

Ini tergantung pada pengembang, mengapa mereka menyinkronkan kait yang dipasang atau kait lainnya dalam hal ini.

  • Tampilkan elemen sementara di tempatnya?

Itu mungkin tidak terjadi sama sekali. Sekali lagi itu tergantung dengan pengembang apa yang ingin mereka capai. Intinya, tidak ada yang harus berjaket lurus. Ketika, misalnya, v-if dirancang, itu bukan karena mereka memahami mengapa seseorang ingin memblokir rendering komponen setiap kali, dan apa yang mereka tempatkan sebagai gantinya dan membuktikannya dengan bodoh. Ada banyak hal yang bisa salah dengan v-if oleh desain pengembang. Anda tidak perlu khawatir tentang apa yang akan ditampilkan di layar selama waktu itu, bukan itu yang perlu dikhawatirkan oleh framework.

Meskipun saya setuju bahwa harapan di sekitar komponen yang dimuat secara dinamis konsisten, perilaku untuk induk menurut saya tidak demikian. Dalam kasus ini, IMO akan mengekspos implementasi anak kepada orang tua dan memaksa orang tua untuk mencari tahu apa yang harus dilakukan dengan komponen dinamis itu. Alih-alih bagaimana data dimuat dan status komponen anak harus terserah pada anak. Jika memuat async maka perlu beberapa cara untuk menjelaskan kepada Vue apa yang harus dirender di tempatnya (atau tidak dirender). Cara terbaik untuk menanganinya adalah bagaimana kerangka kerja sudah bekerja, daripada memperkenalkan kompleksitas baru.

FYI: Anda setuju ini perlu diimplementasikan, namun, itu akan memperkenalkan kompleksitas yang Anda tangisi dan dia merasa itu mungkin dilakukan nanti ketika melanggar perubahan diperkenalkan daripada di Vue 3. Intinya adalah dia merasa itu diperlukan .

Selanjutnya, saya tidak sepenuhnya mengikuti argumen Anda:

Apa yang Anda katakan seperti menambahkan fitur v-if/v-clock/v-show akan mendorong praktik buruk sehingga kami lebih baik membodohi kerangka kerja dengan menghapus fitur-fitur itu

Sementara dalam kasus ini, kita dapat dengan jelas melihat bahwa memperkenalkan komponen async yang menunggu pemasangan atau dibuat akan menyebabkan praktik buruk, tidak jelas apakah hal ini terjadi. Kedua, menimbulkan pertanyaan, bahkan jika itu memang menyebabkan praktik buruk, kita harus memilih untuk memperbaikinya , daripada menggunakannya sebagai pembenaran untuk membuat praktik buruk baru. Jika Anda mengetahui praktik buruk yang dibuat oleh v-if , dll... Saya mengundang Anda untuk membagikan secara eksplisit (dalam edisi lain tentu saja) apa masalahnya, daripada mencoba menggunakannya sebagai pembenaran untuk diskusi yang berbeda.

Saya hanya menunjukkan arahan tersebut sebagai contoh fitur yang dapat digunakan secara tidak benar untuk memblokir rendering komponen yang mirip dengan apa yang Anda katakan tentang async... . Tidak ada yang salah dengan mereka. Jadi haruskah kita menghapus arahan itu hanya karena seseorang dapat menggunakan "praktik buruk" untuk membuat komponen yang menampilkan halaman kosong selama satu menit? Sebenarnya Anda tidak melihat orang melakukan itu karena itu tidak terjadi, kecuali jika Anda mencoba memberikan contoh kejahatan yang paling mengerikan.

Dengar, intinya adalah, jika Anda belum dapat melihat use case apa pun, maka jangan katakan orang lain akan menggunakannya dengan buruk dan oleh karena itu tidak boleh dilakukan. Praktik buruk adalah masalah ketidaktahuan dan seseorang yang bodoh mungkin tidak pernah menggunakan fitur ini sama sekali.

Seseorang menanyakan ini https://github.com/vuejs/vue/issues/7209#issuecomment -424349370 di atas sana dan tidak ada yang menjawabnya sejauh yang saya lihat. Ini sejauh ini menunjukkan dengan tulus bahwa Vue tertinggal di bagian ini. Bagian arsitektur ini dirancang ketika async belum ada. Jadi memperbaruinya untuk memenuhi persyaratan modern untuk arsitektur modern adalah ide yang bagus. Kalau tidak, sisanya adalah peretasan dan solusi yang membutuhkan cara khusus untuk melakukannya daripada melakukan apa yang terjadi di industri.

Namun, saya belum yakin, tetapi melihat API fungsional baru secara sekilas sepertinya sebenarnya mungkin untuk melakukan ini. Karena fungsional itu berarti seseorang dapat melakukan hal-hal tertentu yang tidak dapat mereka lakukan secara objektif, seperti kait siklus hidup async.

Dengar, intinya adalah, jika Anda belum dapat melihat use case apa pun, maka jangan katakan orang lain akan menggunakannya dengan buruk dan oleh karena itu tidak boleh dilakukan. Praktik buruk adalah masalah ketidaktahuan dan seseorang yang bodoh mungkin tidak pernah menggunakan fitur ini sama sekali.

Tidak pernah membuat poin itu, saya membuat poin bahwa saya ingin melakukan tindakan async secara default tanpa pernah memblokir komponen dari rendering. Tidak intuitif bahwa melakukan tindakan async dalam blok mounted atau created akan menyebabkan rendering komponen tertunda. Dengan asumsi ini masalahnya, saya malah akan melihat kompleksitas muncul dari bagaimana seorang konsumen, yang menginginkan fungsionalitas saat ini akan melanjutkan. Argumen sejauh ini bukanlah apa yang diminta, tidak dapat dilakukan, melainkan apa yang diminta harus menjadi default. Anda sudah dapat memblokir rendering komponen Anda dengan mengganti template yang ditampilkan berdasarkan v-if="loaded" .

Sekarang untuk membuat tanpa memblokir kode terlihat seperti ini:
Saat ini kode itu adalah:

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

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

Dan untuk merender dengan pemblokiran terlihat sama persis, karena Anda sebenarnya tidak dapat memblokir. Dengan asumsi async created() benar-benar memblokir komponen. Kemudian kita sekarang memiliki pemisahan kode. Untuk menampilkan pemintal, kami menulis:

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

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

dan abaikan saja rendering komponen di layar yang kita tulis

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

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

Apa manfaat penambahan penyederhanaan pemblokiran ini agar tidak membuat pemblokiran menjadi lebih rumit? Aku hanya tidak melihatnya.

Penanganan ketergantungan untuk komponen

@ yyx99803 Silakan lihat ini, ini tidak sempurna, tetapi tetap menggunakan scenerio kasus yang kompleks.

Oke, inilah kasus penggunaan yang bisa ditangani dengan elegan jika kait siklus hidup memiliki async ... menunggu:
_Saya sebenarnya ingin melakukan ini di aplikasi dan mendapat kode jelek untuk mencapai ini. Ini adalah contoh yang sangat dibuat-buat dari coz_

Saya membutuhkan komponen A untuk menunggu pengait mounted komponen B && C menyala sebelum memasang sendiri. Jadi komponen A mounted harus menunggu pengait created , yang memicu pemasangan komponen B && C yang menunggu pemicu _(yang sebenarnya dapat melakukan sesuatu sebelum menunggu)_. Masalahnya lebih mudah dengan cara ini dan jauh lebih bersih dan intuitif karena semuanya tetap di satu tempat untuk komponen yang bersangkutan.

Sebuah memancarkan acara pemicu dan mendengarkan tanggapan dari B dan C _ (B dan C menunggu sinyal A 's sebelum melanjutkan, acara kemudian memancarkan sekali dipasang) _ sebelum melanjutkan, sederhana. Ini lebih seperti skenario ketergantungan untuk komponen tanpa data asing yang berserakan di tempat lain untuk manajemen negara.

Komponen hosting utama , semua komponen dimuat bersama, tetapi tunggu yang tepat menggunakan acara dan async... menunggu. Tidak peduli apa yang dilakukan anak-anak ini, mereka memesan sendiri.

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

komponen A mengontrol pemasangan B dan C sebagai dependensi. Pemicunya dapat dilakukan nanti di kait lain atau bahkan melalui acara UX dari komponen yang sama. Berikut ini hanya untuk memamerkan ide di sini.

<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>

komponen 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>

komponen 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>

Kode di atas dapat disederhanakan lebih lanjut dengan mixin melihat ada banyak cuplikan kode duplikat, saya hanya ingin itu jelas. Metode wasMounted dapat dikalengkan dalam mixin dan digunakan di ketiga komponen.

Di sini kita dapat dengan jelas melihat apa yang diharapkan setiap komponen tanpa kode peretasan atau router lain yang berserakan di tempat lain untuk mengontrol hal yang sama. Sangat membingungkan untuk benar-benar melakukan ini tanpa fitur ini, percayalah saya telah melakukan ini di sebuah aplikasi.

Ini jelas menghilangkan kode yang tidak perlu rumit dan tidak dapat dipelihara.

Sekarang bayangkan ini di Aplikasi besar, dengan 32 komponen pendorong yang berperilaku berbeda. Anda hanya akan memiliki sekitar 3 poin dalam pikiran, yang dapat direduksi menjadi 2 jika Anda memasukkan mixin.

Membuat semuanya tetap segar

Karena ini tidak hanya terbatas untuk dipasang dan dibuat, tetapi sebenarnya harus bekerja dengan semua kait siklus hidup lainnya. Bayangkan jika ini ada di hook beforeActivate / beforeUpdate baru yang mengkilap. Kita bisa membuat komponen menunggu _activation/update_ dan hanya _activate/update_ ketika penyegaran dilakukan setiap kali komponen _activated/updated_; memastikan hal-hal tetap segar.

Daftar ini tidak ada habisnya setelah ini diterapkan.

Dengar, intinya adalah, jika Anda belum dapat melihat use case apa pun, maka jangan katakan orang lain akan menggunakannya dengan buruk dan oleh karena itu tidak boleh dilakukan. Praktik buruk adalah masalah ketidaktahuan dan seseorang yang bodoh mungkin tidak pernah menggunakan fitur ini sama sekali.

Tidak pernah membuat poin itu, saya membuat poin bahwa saya ingin melakukan tindakan async secara default tanpa pernah memblokir komponen dari rendering. Tidak intuitif bahwa melakukan tindakan async dalam blok mounted atau created akan menyebabkan rendering komponen tertunda. Dengan asumsi ini masalahnya, saya malah akan melihat kompleksitas muncul dari bagaimana seorang konsumen, yang menginginkan fungsionalitas saat ini akan melanjutkan. Argumen sejauh ini bukanlah apa yang diminta, tidak dapat dilakukan, melainkan apa yang diminta harus menjadi default. Anda sudah dapat memblokir rendering komponen Anda dengan mengganti template yang ditampilkan berdasarkan v-if="loaded" .

Sekarang untuk membuat tanpa memblokir kode terlihat seperti ini:
Saat ini kode itu adalah:

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

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

Dan untuk merender dengan pemblokiran terlihat sama persis, karena Anda sebenarnya tidak dapat memblokir. Dengan asumsi async created() benar-benar memblokir komponen. Kemudian kita sekarang memiliki pemisahan kode. Untuk menampilkan pemintal, kami menulis:

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

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

dan abaikan saja rendering komponen di layar yang kita tulis

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

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

Apa manfaat penambahan penyederhanaan pemblokiran ini agar tidak membuat pemblokiran menjadi lebih rumit? Aku hanya tidak melihatnya.

Ini adalah bootcamp Vue 101 dan tidak ada yang baru di sana... tidak cukup untuk mencakup kasus di atas misalnya. Idenya di sini adalah untuk mengurangi kompleksitas di userland di mana Vue sebenarnya digunakan dan lebih mudah untuk mencari alasan tentang kode.

Render di sini bukanlah masalahnya, itu apa yang terjadi sebelum render yang sebenarnya merupakan konsekuensi. Kami menginginkan kebebasan untuk melakukan sesuatu sebelum melanjutkan atau merender komponen. Bagaimanapun, ini juga tidak ada hubungannya dengan memblokir rendering sama sekali. Ada banyak kait siklus hidup yang didukung Vue dan ini sebenarnya dapat berguna jika ada cara untuk menangani kode asinkron terhadap kait lain. Idenya adalah agar Vue menghormati async secara internal sebelum pergi ke fungsi hook berikutnya.

Saya benar-benar bingung dengan ini, alih-alih menggabungkan B & C ke A, saya akan memindahkan kode ke "memuat A" ke A.js dan kemudian meminta A.js memperbarui "B.data" dan "C.data" . Dengan begitu jika A.data berubah karena alasan apa pun, komponen lain secara otomatis dirender daripada mencoba mendelegasikan
kontrol dari satu komponen ke komponen lainnya. Bahkan dalam kasus yang dibagikan, saya masih akan memisahkan data untuk merender A dari komponen A . Kami telah menggunakan satu kelas yang berisi metode seperti fetchData dan hasInitialized dimana yang terakhir adalah janji dan yang pertama menyelesaikan yang terakhir.
Menggabungkan komponen secara langsung menciptakan pohon ketergantungan yang tidak terduga yang mencegah komponen agar tidak dapat digunakan kembali dan memungkinkan vue untuk merendernya dengan benar.

Atau, saya bahkan akan emit acara langsung ke induk A, B, dan C, dan bukan pada lingkup global, dan membiarkan induk memutuskan apakah akan merender B dan C, yaitu

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

Ada apa dengan A yang dalam hal ini kita perlu merender sebelum B dan C merender. Jika ada hal-hal dalam metode created() , tidak ada yang mencegahnya dari mengisi toko melalui kelas javascript atau menggunakan modul store . Tetapi kasus penggunaan eksplisit akan lebih membantu, yaitu apa UX dari cerita pengguna yang tidak dapat ditangkap?

Idenya adalah agar Vue menghormati async secara internal sebelum pergi ke fungsi hook berikutnya.

Tentu bagian itu masuk akal, tetapi saya tidak yakin mengapa contohnya perlu berbelit-belit, mengapa tidak mengatakan sesuatu seperti kisah pengguna ini:

Komponen saya memiliki async beforeMount dan async mounted , tetapi kode di mounted diaktifkan sebelum kode di beforeMount selesai. Bagaimana cara memblokir mounted agar tidak diaktifkan sebelum beforeMount selesai?

Seperti apa permintaan aslinya, jadi pertanyaan yang diajukan dalam respons kedua menurut saya masih relevan: https://github.com/vuejs/vue/issues/7209#issuecomment -350284784

Penutupan untuk saat ini, tetapi jangan ragu untuk menindaklanjuti dengan alasan / kasus penggunaan / implikasi yang lebih konkret.

Apakah sebenarnya ada kasus penggunaan yang valid untuk perlu memblokir kait siklus hidup yang dieksekusi sebelumnya, atau apakah kait siklus hidup benar untuk disinkronkan. Sejauh ini diskusi bersifat filosofis (seperti yang cenderung dilakukan oleh diskusi arsitektur yang baik), tetapi sebenarnya pertanyaannya adalah apakah ada alasan bagus yang sebenarnya untuk melakukan ini. Saya tidak ragu sedetik pun masuk akal bagi kerangka kerja untuk menunggu kode async. Saya mengalami masalah yang tepat di N perpustakaan lain yang tidak melakukan itu atau meneruskan panggilan balik (atau meneruskan panggilan balik tetapi tidak meneruskan panggilan balik ke panggilan balik). Namun, sebenarnya masuk akal untuk memiliki kait siklus hidup async atau apakah alasan hasil dari mencoba melakukan sesuatu yang "tidak boleh dilakukan"?

Yaitu apa yang terjadi ketika Anda mencoba untuk unmount komponen yang belum selesai menjadi created , wow, itu akan buruk untuk menunggu itu. Atau destroying yang belum selesai mounted , saya tidak iri dengan pelaksana fungsi itu.

Saya benar-benar bingung dengan ini, alih-alih menggabungkan B & C ke A, saya akan memindahkan kode ke "memuat A" ke A.js dan kemudian meminta A.js memperbarui "B.data" dan "C.data" . Dengan begitu jika A.data berubah karena alasan apa pun, komponen lain secara otomatis dirender daripada mencoba mendelegasikan

Itu kompleksitas meningkat, praktik buruk. Coba tulis di sini secara lengkap mari kita lihat apa yang Anda maksud, tetapi bagi saya Anda baru saja meningkatkan kerumitannya.

kontrol dari satu komponen ke komponen lainnya. Bahkan dalam kasus yang dibagikan, saya masih akan memisahkan data untuk merender A dari komponen A . Kami telah menggunakan satu kelas yang berisi metode seperti fetchData dan hasInitialized dimana yang terakhir adalah janji dan yang pertama menyelesaikan yang terakhir.

Ini sekarang terlalu banyak menggabungkan komponen. Kami ingin ini bekerja tanpa yang lain kecuali untuk A.

Menggabungkan komponen secara langsung menciptakan pohon ketergantungan yang tidak terduga yang mencegah komponen agar tidak dapat digunakan kembali dan memungkinkan vue untuk merendernya dengan benar.

Sebenarnya Anda kehilangan intinya, ini digabungkan secara longgar hingga masing-masing dapat digunakan dan dipelihara tanpa mempengaruhi yang lain. Sebenarnya Anda dapat menjatuhkan salah satu dari mereka beberapa kali di mana saja tanpa menulis kode lagi di induknya di luar <component-x /> , tidak v-if , vuex untuk mengelola statusnya atau apa pun.

Saya menggabungkannya A ke B dan C hanya untuk menunjukkan, saya bisa membagi ini dengan baik atau hanya menghitung berapa banyak komponen yang merespons kemudian melanjutkan ketika jumlah yang diharapkan tercapai (2 dalam kasus ini) misalnya:

 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

Bagaimanapun, itu sebabnya saya mengatakan Penanganan Ketergantungan Komponen, ini diinginkan dan diharapkan, tetapi harus dilakukan dalam kompleksitas sesedikit mungkin karena semakin kompleks semakin membingungkan.

Atau, saya bahkan akan emit acara langsung ke induk A, B, dan C, dan bukan pada lingkup global, dan membiarkan induk memutuskan apakah akan merender B dan C, yaitu

Saya tahu Anda akan mengatakan ini, tetapi ini tidak diinginkan. Komponen-komponen ini tidak boleh dikendalikan oleh hal lain, maka saya tekankan bahwa komponen utama tidak terlalu peduli dengan apa yang dilakukan anak-anaknya, mereka harus tetap mandiri. Saya ingin dapat menempatkannya di mana saja di Aplikasi dan tetap membuat hal yang sama ini berfungsi . Saat Anda melakukan apa yang Anda katakan di sana, perhatikan bagaimana semuanya pecah. Tetapi saya dapat dengan mudah meletakkan komponen di mana saja di pohon DOM bahkan tanpa tersentak, dan semuanya akan berfungsi. Saya bahkan dapat memiliki banyak salinan ini dan itu akan tetap berfungsi. Semua berkat async ... await pada siklus hidup.

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

Ada apa dengan A yang dalam hal ini kita perlu merender sebelum B dan C merender.

Kami ingin setiap komponen melakukan pekerjaan unik sebelum dipasang. Tetapi semua komponen hanya akan dirender ketika setiap komponen lain telah selesai melakukan pekerjaan itu. Itulah cerita di sini.
Jadi semoga sukses dengan manajemen negara dan v-if hanya untuk mengontrol ini belum lagi data aktual yang mungkin akan dihasilkan di vuex store . Anda akan memiliki banyak kode duplikat yang ditulis di mana pun komponen tersebut digunakan. Katakanlah Anda memiliki komponen lain yang hanya meng-host A dan C dan dalam konfigurasi yang berbeda? Anda harus menulis manajemen status vuex v-if itu untuk membuatnya berfungsi. Apakah kamu melihat masalahnya? mari saya ilustrasikan:

  // 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 ...,
}

..... dan seterusnya

alih-alih hanya menggunakan komponen tanpa pernah melakukan apa pun di orang tua seperti:

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

... Dan seterusnya

Jika ada hal-hal dalam metode created() , tidak ada yang mencegahnya dari mengisi toko melalui kelas javascript atau menggunakan modul store . Tetapi kasus penggunaan eksplisit akan lebih membantu, yaitu apa UX dari cerita pengguna yang tidak dapat ditangkap?

Ingat apa yang saya katakan tentang manajemen negara yang berserakan di mana-mana? Kami tidak ingin karena mengelola komponen ini berarti kami akan mengelola banyak hal di tempat lain, yang sangat kompleks daripada apa yang baru saja saya lakukan. Selain itu, itu tidak akan melakukan apa yang saya inginkan; hanya mount ketika setiap komponen telah menyelesaikan apa yang seharusnya dilakukan dengan sedikit kerumitan.

Idenya adalah agar Vue menghormati async secara internal sebelum pergi ke fungsi hook berikutnya.

Tentu bagian itu masuk akal, tetapi saya tidak yakin mengapa contohnya perlu berbelit-belit, mengapa tidak mengatakan sesuatu seperti kisah pengguna ini:

Komponen saya memiliki async beforeMount dan async mounted , tetapi kode di mounted diaktifkan sebelum kode di beforeMount selesai. Bagaimana cara memblokir mounted agar tidak diaktifkan sebelum beforeMount selesai?

Intinya adalah kita ingin sesuatu terjadi sebelum salah satu komponen ini dirender dan dapat digunakan tanpa terlalu banyak masukan di luar komponen itu sendiri. Ini adalah hal aktual yang saya perhatikan bisa saya lakukan lebih baik jika ini tersedia aplikasi yang kami buat. Saya akhirnya menulis kode yang memiliki banyak mixin, vuex, dan orang tua yang sangat berpasangan di mana-mana (menggunakan mixin) komponennya digunakan karena ini hilang. Ini bukan cerita yang berbelit-belit, saya sebenarnya menceritakan apa yang terjadi dengan cara yang sederhana. Kami harus memikirkan kembali bagaimana UI seharusnya dirancang dan dipelihara. Itu menjadi sedikit kurang menarik secara visual dan banyak kode yang rumit.

Apakah Anda melihat berapa banyak hal rumit yang Anda perkenalkan ke dalam pengaturan sederhana ini yang baru saja diselesaikan oleh async kecil itu ... fitur menunggu dalam siklus hidup?

@wparad

Yaitu apa yang terjadi ketika Anda mencoba untuk meng-unmount komponen yang belum selesai dibuat, wow, itu akan buruk untuk menunggu itu. Atau menghancurkan yang belum selesai dipasang, saya tidak iri pada pelaksana fungsi itu.

Di sinilah:

... memerlukan pemikiran ulang/penulisan ulang arsitektur yang mendasar untuk dicapai, dan berpotensi mematahkan banyak logika yang bergantung pada sifat sinkron dari kait siklus hidup...

... bagian yang saya yakini telah disebutkan oleh Anda. Kami membutuhkan cara untuk menangani kasus tepi ini dan mungkin lebih dari itu. Dengan kata lain, maksud kita harus berfungsi tanpa merusak aplikasi.

Dalam semua kasus itu saya akan menggunakan batas waktu untuk memeriksa atau membatalkan penantian, seperti kebanyakan operasi async yang mungkin gagal.

Tetapi jika Anda melihat contoh yang saya sajikan dengan cermat, Anda akan mengerti apa yang saya maksud. Ini bisa menyelesaikan banyak hal, tanpa banyak kode yang ditulis di mana pun. Sebenarnya Aplikasi kami bisa menjadi jauh lebih baik dengan basis kode yang jauh lebih kecil, terdefragmentasi, dan mudah dipahami jika ini memungkinkan.
Hal tentang fitur semacam ini adalah Anda hanya melihat kepentingannya begitu Anda menemukan penghalang jalan. Saya pertama kali datang ke halaman ini ketika kami memikirkan banyak solusi tentang contoh yang baru saja saya berikan ini. Saya tidak datang untuk mencari bantuan, itu untuk mengajukan permintaan fitur karena kami melihat itu tidak tersedia di Vue.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

bfis picture bfis  ·  3Komentar

gkiely picture gkiely  ·  3Komentar

bdedardel picture bdedardel  ·  3Komentar

franciscolourenco picture franciscolourenco  ·  3Komentar

guan6 picture guan6  ·  3Komentar