Vue 3 中的可挂组件是什么?

yaq*_*awa 2 vue.js vuejs3

我正在阅读这篇文章:https : //v3.vuejs.org/guide/component-dynamic-async.html#using-with-suspense

它指的是一个称为“可悬浮”组件的概念。

我已经研究过,但我找不到任何关于所谓的“悬浮”组件的信息。

谁能解释一下它是什么?谢谢!

And*_*hiu 5

“Supensible”意味着可替换为后备内容,而父级<Suspense>解析async在其<template #default>.

这个概念是从 React 的Suspense API借来的。


更详细地说,<Suspense>是一个内置的 Vue 3 组件,它呈现 ,<template #fallback>而不是<template #default>, 直到async解析默认模板中的所有子组件。

为了成为sususible,组件的渲染需要依赖一个 promise:

  • 使用加载 () => import('some/path')
  • async/await在其setup函数中使用(或任何其他形式的 Promise 语法)

一个悬浮的组件suspensed包括在时<Suspense>的默认模板,而其母公司<Suspense>并没有解决所有的悬浮的成分,即使suspensed组件本身已经解决。

显然,<Suspense>组件本身是可悬置的,悬置可以嵌套。


这里有一个更详细的解释<Suspense>的Vue公司3。


在其他用法中,<Suspence>提供了一种优雅和直观的方法来解决必须包装子组件和模板以v-if防止尚未加载的数据上不存在的属性的常见问题。

一个典型的 Vue 2 示例:

Vue.config.devtools = false;
Vue.config.productionTip = false;

Vue.component('render-items', {
  props: ['items'],
  template: `<table>
  <tr>
    <th>Id</th>
    <th>User Id</th>
    <th>Title</th>
  </tr>
  <tr v-for="(item, key) in items" :key="key">
    <td v-text="item.id"></td>
    <td v-text="item.userId"></td>
    <td v-text="item.title"></td>
  </tr>
</table>`  
});

new Vue({
  el: '#app',
  data: () => ({
    items: []
  }),
  computed: {
    hasData() {
      return this.items.length;
    }
  },  
  async created() {
    const items = await fetch('https://jsonplaceholder.typicode.com/posts')
      .then(r => r.json());
    this.items = items;
  }
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.12/vue.js"></script>
<div id="app">
  <render-items :items="items" v-if="hasData"></render-items>
  <template v-else>loading...</template>
</div>
Run Code Online (Sandbox Code Playgroud)

Vue 3 中的相同示例(或多或少),使用<Suspense>async setup

const RenderItems = Vue.defineComponent({
  async setup() {
    const items = await fetch('https://jsonplaceholder.typicode.com/posts')
      .then(r => r.json());
    return Vue.reactive({ items });
  },
  template: `<table>
  <tr>
    <th>Id</th>
    <th>User Id</th>
    <th>Title</th>
  </tr>
  <tr v-for="(item, key) in items" :key="key">
    <td v-text="item.id"></td>
    <td v-text="item.userId"></td>
    <td v-text="item.title"></td>
  </tr>
</table>`
});
const App = { components: { RenderItems }};
Vue.createApp(App).mount('#app');
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@next/dist/vue.global.prod.js"></script>
<div id="app">
  <Suspense>
    <template #default>
      <render-items></render-items>
    </template>
    <template #fallback>
      loading...
    </template>
  </Suspense>
</div>
Run Code Online (Sandbox Code Playgroud)

一个主要优点是在 Vue 3 示例中,我们可以在子组件中包含数据获取器(和数据)。这在 Vue 2 中是不可能的,因为:

  • 子组件仅在数据加载后创建
  • 父组件需要知道条件何时更改(因此它需要访问实际条件),以便在呈现后备内容或子组件之间切换。

在 Vue 2 中最简单的方法实际上是在父组件中加载数据并将结果通过 props 传递给子组件。如果您有很多子组件,则此模式可能会变得混乱。

在 Vue 3 中,加载数据和检查条件的责任完全由子组件承担。父级不需要访问实际情况。

就像<template><Suspense>不创建 DOM 元素。

在上面的 Vue 3 例子中,<RenderItems />是悬而未决的。