首页 > 编程笔记

Vue动态组件和异步组件(小白必读)

Vue.js提供了两种特殊组件:动态组件和异步组件。

Vue动态组件

有时候,一个组件内部需要根据不同的选择,显示不同的组件。如在标签卡布局里面,单击不同的标签,内容块需要显示该标签对应的内容。

Vue.js 中提供了 component 元素组件,可以动态地显示指定的组件。component 元素中有个 is 属性,通过给 is 属性绑定一个组件名称,component 就可以显示该组件名称对应的组件,语法如下:
<component v-bind:is="currTabComponent"></component>
如果 currTabComponent 的值是 test-comp1,就表示显示名称为 test-comp1 的组件。样例代码如下:
... 
<div id="app"> 
  <!-- Tabs 标签 --> 
  <button 
    v-for="tab in tabs" 
    :key="tab" 
    :class="['tab-button', { active: currentTab === tab }]" 
    @click="currentTab = tab" 
  > 
    {{ tab }} 
  </button> 
 
  <!-- 显示当前 tab 对应的组件 --> 
  <component :is="currentTabComponent" class="tab"></component> 
</div> 
 
<script> 
// 定义 Home 组件 
Vue.component('DynamicComponent', { 
  template: '<div>Component Home</div>' 
}); 
 
// 定义组件 1 
Vue.component('DynamicComp1', { 
  template: '<div>Component 111</div>' 
}); 
 
// 定义组件 2 
Vue.component('DynamicComp2', { 
  template: '<div>Component 222</div>' 
}); 
 
const vm = new Vue({ 
  el: "#app", 
  data: { 
    currentTab: 'DynamicComponent', 
    tabs: ['DynamicComponent', 'DynamicComp1', 'DynamicComp2'] 
  }, 
  computed: { 
    currentTabComponent: function() { 
      // 返回 tab 对应组件的名称,以便在 component 中动态显示 
      return 'Dynamic' + this.currentTab.charAt(0).toUpperCase() + this.currentTab.slice(1); 
    } 
  } 
}); 
</script> 
...

Vue异步组件

在大型应用中,开发人员可能需要将应用分割成小的代码块,并且只在需要的时候才从服务器加载所需的模块。

为了简化,Vue.js 允许开发人员以一个工厂函数的方式定义组件,这个工厂函数会异步解析组件的定义。Vue.js 只有在这个组件需要被渲染的时候才会被触发,并且会把结果缓存起来供未来重渲染,代码如下:
Vue.component('async-example', function (resolve, reject) { 
  setTimeout(function () { 
    // 在此处定义组件 
    resolve({ 
      template: ` 
        <div> 
          我是异步加载的哦 
        </div> 
      ` 
    }); 
  }, 1000); 
});
这个工厂函数会收到一个 resolve 回调,这个回调函数会在从服务器得到组件定义的时候被调用。开发人员也可以调用 reject(reason)来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于开发人员自己。

keep-alive

在前面的动态组件案例中,用户单击 tab 切换组件后,回到以前 tab 对应的组件上时,该组件会被重新渲染。

有时候希望回到上次单击的状态,这时候,开发人员可以在 component 的外面包含 keep-alive 元素,这样就可以保持这些组件的状态,以避免反复重渲染导致的性能问题,代码如下:
<!-- 失活的组件将会被缓存! --> 
<keep-alive> 
  <component v-bind:is="currentTabComponent"></component> 
</keep-alive>

推荐阅读