Komponen dinamik & komponen tak segerak


Halaman ini menganggap anda telah membaca Asas Komponen. Jika anda masih belum tahu banyak tentang komponen, saya syorkan anda membacanya terlebih dahulu.


Direktori


Gunakan keep-alive


pada komponen dinamik sebelum ini kami telah menggunakan atribut is untuk menukar komponen yang berbeza dalam antara muka berbilang tab: keep-alive

我们之前曾经在一个多标签的界面中使用 is 特性来切换不同的组件:

<component v-bind:is="currentTabComponent"></component>

当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。例如我们来展开说一说这个多标签界面:

1.gif

你会注意到,如果你选择了一篇文章,切换到 Archive 标签,然后再切换回 Posts,是不会继续展示你之前选择的文章的。这是因为你每次切换新标签的时候,Vue 都创建了一个新的 currentTabComponent 实例。

重新创建动态组件的行为通常是非常有用的,但是在这个案例中,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。

<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

来看看修改后的结果:

2.gif

现在这个 Posts 标签保持了它的状态 (被选中的文章) 甚至当它未被渲染时也是如此。你可以在这个 fiddle 查阅到完整的代码。

注意这个 <keep-alive> 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。

你可以在 API 参考文档 查阅更多关于 <keep-alive>

Vue.component('async-example', function (resolve, reject) {
  setTimeout(function () {
    // 向 `resolve` 回调传递组件定义
    resolve({
      template: '<div>I am async!</div>'
    })
  }, 1000)
})

Apabila bertukar antara komponen ini, kadangkala anda ingin mengekalkan keadaan komponen ini untuk mengelakkan masalah prestasi yang disebabkan oleh pemaparan semula berulang. Sebagai contoh, mari kita kembangkan dan bincangkan tentang antara muka berbilang tab ini:

1.gif🎜🎜Anda akan perasan bahawa jika anda memilih artikel, tukar kepada teg Arkib dan kemudian tukar kembali ke Catatan, ya Artikel yang anda pilih sebelum ini tidak akan dipaparkan lagi. Ini kerana Vue mencipta contoh currentTabComponent setiap kali anda bertukar kepada tab baharu. 🎜🎜Mencipta semula gelagat komponen dinamik selalunya sangat berguna, tetapi dalam kes ini, kami lebih suka bahawa tika komponen teg tersebut dicache apabila ia mula-mula dibuat. Untuk menyelesaikan masalah ini, kita boleh membalut komponen dinamiknya dengan elemen <keep-alive>. 🎜
Vue.component('async-webpack-example', function (resolve) {
  // 这个特殊的 `require` 语法将会告诉 webpack
  // 自动将你的构建代码切割成多个包,这些包
  // 会通过 Ajax 请求加载
  require(['./my-async-component'], resolve)
})
🎜Jom lihat hasil yang diubah suai: 🎜🎜2.gif🎜🎜Kini teg Siaran mengekalkan statusnya (siaran terpilih) walaupun ia tidak dipaparkan. Anda boleh menyemak kod lengkap di fiddle ini🎜. 🎜🎜🎜Perhatikan bahawa <keep-alive> memerlukan komponen yang ditukar mempunyai namanya sendiri, sama ada melalui pilihan name atau pendaftaran tempatan/global. 🎜🎜🎜Anda boleh membaca lebih lanjut tentang <simpan dalam dokumen rujukan API🎜 -alive> butiran. 🎜🎜🎜🎜

Komponen Asynchronous


Dalam aplikasi yang besar, kita mungkin perlu membahagikan aplikasi kepada ketulan kod yang lebih kecil dan memuatkan modul dari pelayan hanya apabila diperlukan. Untuk memudahkan, Vue membenarkan anda mentakrifkan komponen anda sebagai fungsi kilang, yang akan menghuraikan definisi komponen anda secara tidak segerak. Vue hanya akan mencetuskan fungsi kilang apabila komponen perlu dipaparkan dan cache keputusan untuk pemaparan semula pada masa hadapan. Contohnya:

Vue.component(
  'async-webpack-example',
  // 这个 `import` 函数会返回一个 `Promise` 对象。
  () => import('./my-async-component')
)

Seperti yang anda lihat, fungsi kilang ini akan menerima panggilan balik resolve, yang akan dipanggil apabila anda mendapat definisi komponen daripada pelayan. Anda juga boleh memanggil reject(reason) untuk menunjukkan kegagalan beban. setTimeout di sini adalah untuk tunjuk cara untuk mendapatkan komponen terpulang kepada anda. Pendekatan yang disyorkan ialah menggunakan komponen tak segerak dengan ciri pemisahan kod webpack resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:

new Vue({
  // ...
  components: {
    'my-component': () => import('./my-async-component')
  }
})

你也可以在工厂函数中返回一个 Promise,所以把 webpack 2 和 ES2015 语法加在一起,我们可以写成这样:

const AsyncComponent = () => ({
  // 需要加载的组件 (应该是一个 `Promise` 对象)
  component: import('./MyComponent.vue'),
  // 异步组件加载时使用的组件
  loading: LoadingComponent,
  // 加载失败时使用的组件
  error: ErrorComponent,
  // 展示加载时组件的延时时间。默认值是 200 (毫秒)
  delay: 200,
  // 如果提供了超时时间且组件加载也超时了,
  // 则使用加载失败时使用的组件。默认值是:`Infinity`
  timeout: 3000
})

当使用局部注册的时候,你也可以直接提供一个返回 Promise:

rrreee
Anda juga boleh kembalikan Promise dalam fungsi kilang, jadi menambahkan sintaks webpack 2 dan ES2015 bersama-sama, kita boleh menulis seperti ini:

rrreeeApabila menggunakan Apabila mendaftar separa, anda juga boleh terus menyediakan fungsi yang mengembalikan Janji: rrreeeJika anda seorang Browserify

Pengguna juga suka untuk menggunakan komponen tak segerak Malangnya, pengarang alat ini
dengan jelas menyatakan

bahawa pemuatan asynchronous "tidak akan disokong oleh Browserify", sekurang-kurangnya tidak secara rasmi. Komuniti Browserify telah menemui
beberapa penyelesaian

yang mungkin berguna untuk aplikasi kompleks sedia ada. Untuk senario lain, kami mengesyorkan menggunakan webpack secara langsung untuk mempunyai sokongan async kelas pertama terbina dalam. . Jika anda mahu Jika anda menggunakan sintaks di atas dalam komponen penghalaan

Vue Router

, anda mesti menggunakan Vue Router 2.4.0+ versi.