Composants dynamiques et composants asynchrones


Cette page suppose que vous avez lu Bases des composants. Si vous ne savez pas encore grand-chose sur les composants, je vous recommande de le lire d'abord.


Répertoire


Utilisez keep-alivekeep-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>


sur des composants dynamiques Nous avons déjà utilisé l'attribut is pour basculer entre différents composants dans une interface multi-onglets :


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

Lorsque vous basculez entre ces composants, vous souhaitez parfois conserver l'état de ces composants pour éviter les problèmes de performances causés par des rendus répétés. Par exemple, développons et parlons de cette interface multi-onglets : 🎜🎜1.gif🎜🎜Vous remarquerez que si vous sélectionnez un article, passez à la balise Archive, puis revenez aux Posts, oui Les articles que vous avez sélectionnés précédemment ne seront plus affichés. En effet, Vue crée une nouvelle instance currentTabComponent chaque fois que vous passez à un nouvel onglet. 🎜🎜Recréer le comportement des composants dynamiques est souvent très utile, mais dans ce cas, nous préférons que les instances de composants de ces balises soient mises en cache lors de leur première création. Pour résoudre ce problème, nous pouvons envelopper son composant dynamique avec un élément <keep-alive>. 🎜
Vue.component('async-webpack-example', function (resolve) {
  // 这个特殊的 `require` 语法将会告诉 webpack
  // 自动将你的构建代码切割成多个包,这些包
  // 会通过 Ajax 请求加载
  require(['./my-async-component'], resolve)
})
🎜Jetons un œil aux résultats modifiés : 🎜🎜2.gif🎜🎜Désormais, la balise Posts conserve son statut (post sélectionné) même lorsqu'elle n'est pas rendue. Vous pouvez consulter le code complet sur ce violon🎜. 🎜🎜🎜Notez que <keep-alive> nécessite que le composant vers lequel vous basculez ait son propre nom, que ce soit via l'option name du composant ou un enregistrement local/global. 🎜🎜🎜Vous pouvez en savoir plus sur <keep dans le document de référence API🎜 -alive> détails. 🎜🎜🎜🎜

Composants asynchrones


Dans les grandes applications, nous devrons peut-être diviser l'application en morceaux de code plus petits et charger un module à partir du serveur uniquement en cas de besoin. Pour simplifier, Vue vous permet de définir votre composant comme une fonction d'usine, qui analysera la définition de votre composant de manière asynchrone. Vue ne déclenchera la fonction d'usine que lorsque le composant doit être rendu et mettra en cache les résultats pour un nouveau rendu futur. Par exemple :

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

Comme vous pouvez le voir, cette fonction d'usine recevra un rappel resolve, qui sera appelé lorsque vous obtiendrez la définition du composant du serveur. Vous pouvez également appeler reject(reason) pour indiquer un échec de chargement. Le setTimeout ici est à titre de démonstration. Comment obtenir le composant dépend de vous. Une approche recommandée consiste à utiliser des composants asynchrones avec la fonctionnalité de fractionnement de code 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
Vous pouvez également renvoie une Promesse dans la fonction d'usine, donc en ajoutant la syntaxe Webpack 2 et ES2015 ensemble, nous pouvons écrire comme ceci :

rrreeeLors de l'utilisation de Lors de votre inscription partiellement, vous pouvez également fournir directement une fonction qui renvoie une Promesse : rrreeeSi vous êtes un Browserify

Les utilisateurs aiment aussi d'utiliser des composants asynchrones Malheureusement, l'auteur de cet outil
a clairement déclaré

que le chargement asynchrone "ne sera pas pris en charge par Browserify", du moins pas officiellement. La communauté Browserify a trouvé
quelques solutions de contournement

qui peuvent être utiles pour les applications complexes existantes. Pour d’autres scénarios, nous vous recommandons d’utiliser directement webpack pour intégrer une prise en charge asynchrone de première classe.

Gérer l'état de chargement

2.3.0+ Nouveau

La fonction d'usine de composants asynchrones ici peut également renvoyer un objet au format suivant : rrreeeRemarque : Si vous le souhaitez Si vous utilisez la syntaxe ci-dessus dans le composant de routage de

Vue Router


, vous devez utiliser la version Vue Router 2.4.0+.

🎜🎜🎜🎜🎜