# 动态组件与异步组件

# 动态组件

<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentComponent"></component>

<!-- 这里时一个变量,其实也可以是常量 -->
<!-- https://cn.vuejs.org/v2/guide/components.html#%E8%A7%A3%E6%9E%90-DOM-%E6%A8%A1%E6%9D%BF%E6%97%B6%E7%9A%84%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9 -->
<component is="currentComponent"></component>

currentComponent的值可以有两种:

  • 已注册组件的名字 Vue.component('组件名', {})
  • 一个组件的选项对象
// 组件的选项对象 
// 完整示例: https://jsfiddle.net/chrisvfritz/b2qj69o1/
{ template: '<div>Home component</div>'}

实列:切换tab选项卡

<div id="app">
  <button @click="changeContent">Home</button>
  <button @click="changeContent">Posts</button>
  <button @click="changeContent">Archive</button>
  <div style="border:1px solid #ccc;">
    <component v-bind:is="currentComponent"></component>
  </div>
</div>
<script>
  Vue.component('home-component', {
    template: `\<div\>Home component\</div\>`
  })
  Vue.component('posts-component', {
    template: `<div>Hosts component</div>`
  })
  Vue.component('archive-component', {
    template: `<div>Archive component</div>`
  })
  var app = new Vue({
    el: '#app',
    data: {
      currentComponent: 'home-component'  
    },
    methods: {
      changeContent: function(event) {
        var tempVal = event.target.innerHTML.toLowerCase();
        this.currentComponent = tempVal + '-component';
      }
    }
  })
</script>

# 在动态组件上使用keep-alive

动态组件会在多个组件之间切换,如果想保持这些组件的状态。可以用keep-alive包裹

默认情况下,每次切换新标签的时候,Vue 都创建了一个新的 currentTabComponent 实例, 组件的状态不会保存

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

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

# 异步组件

大型应用中,可能需要将应用分割为小的组件,只有在需要的时候才从服务器加载一个模块。

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

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

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

# 处理加载状态

这里的异步组件工厂函数也可以返回一个如下格式的对象:

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