Vue 3 中的可挂起组件是什么?
What is a suspensible component in Vue 3?
我正在阅读这篇文章:https://v3.vuejs.org/guide/component-dynamic-async.html#using-with-suspense
它指的是一个名为“suspensible”组件的概念。
我已经研究过,但我找不到任何关于所谓的“suspensible”组件的信息。
谁能解释一下这是什么?谢谢!
一个可暂停的组件将是一个能够使用 Vue 3 中的新项目的组件。一个暂停的项目是加载的东西并且可能需要更长的时间来加载,比如 API 调用。通常,您会在悬念项目内部的项目内部使用 async/await。
这里有很多有用的信息:https://v3.vuejs.org/guide/component-dynamic-async.html#async-components
您可以使用悬念项来说明悬念项内的项正在等待时显示其他内容(例如骷髅装载机)。
“Suspensible” 表示可由回退内容替换,而父 <Suspense>
解析 async
在其 <template #default>
中找到的子组件。
这个概念是从React的Suspense API中借用的。
更详细地说,<Suspense>
是一个内置的 Vue 3 组件,它呈现 <template #fallback>
而不是 <template #default>
,直到默认情况下所有 async
子组件模板已解决。
为了可暂停,组件的渲染需要依赖于一个承诺:
- 使用
() => import('some/path')
加载
- 或在其
setup
函数中使用 async/await
(或任何其他形式的 Promise 语法)
当包含在 <Suspense>
的默认模板中时,可暂停组件 已暂停 ,而其父级 <Suspense>
尚未解决其所有可暂停组件,即使挂起的组件本身已经解决了。
很明显,<Suspense>
组件本身是可以悬浮的,可以嵌套悬浮。
这是 Vue 3 中 <Suspense>
上的 more detailed explanation。
在其他用法中,<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;
}
})
<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>
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');
<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>
一个主要优点是在 Vue 3 示例中,我们可以在子组件中包含数据获取器(和数据)。这在 Vue 2 中是不可能的,因为:
- 子组件仅在数据加载后创建
- 父级需要知道条件何时更改(因此它需要访问实际条件)以便在呈现回退内容或子组件之间切换。
在 Vue 2 中最简单的方法实际上是在父组件中加载数据并将结果通过 props 传递给子组件。如果您有很多子组件,此模式可能会变得混乱。
在 Vue 3 中,加载数据和检查条件的责任完全由子组件承担。家长不需要了解实际情况。
就像 <template>
一样,<Suspense>
不会创建 DOM 元素。
在上面的Vue 3例子中,<RenderItems />
是挂起的。
我正在阅读这篇文章:https://v3.vuejs.org/guide/component-dynamic-async.html#using-with-suspense
它指的是一个名为“suspensible”组件的概念。
我已经研究过,但我找不到任何关于所谓的“suspensible”组件的信息。
谁能解释一下这是什么?谢谢!
一个可暂停的组件将是一个能够使用 Vue 3 中的新项目的组件。一个暂停的项目是加载的东西并且可能需要更长的时间来加载,比如 API 调用。通常,您会在悬念项目内部的项目内部使用 async/await。
这里有很多有用的信息:https://v3.vuejs.org/guide/component-dynamic-async.html#async-components
您可以使用悬念项来说明悬念项内的项正在等待时显示其他内容(例如骷髅装载机)。
“Suspensible” 表示可由回退内容替换,而父 <Suspense>
解析 async
在其 <template #default>
中找到的子组件。
这个概念是从React的Suspense API中借用的。
更详细地说,<Suspense>
是一个内置的 Vue 3 组件,它呈现 <template #fallback>
而不是 <template #default>
,直到默认情况下所有 async
子组件模板已解决。
为了可暂停,组件的渲染需要依赖于一个承诺:
- 使用
() => import('some/path')
加载
- 或在其
setup
函数中使用async/await
(或任何其他形式的 Promise 语法)
当包含在 <Suspense>
的默认模板中时,可暂停组件 已暂停 ,而其父级 <Suspense>
尚未解决其所有可暂停组件,即使挂起的组件本身已经解决了。
很明显,<Suspense>
组件本身是可以悬浮的,可以嵌套悬浮。
这是 Vue 3 中 <Suspense>
上的 more detailed explanation。
在其他用法中,<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;
}
})
<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>
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');
<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>
一个主要优点是在 Vue 3 示例中,我们可以在子组件中包含数据获取器(和数据)。这在 Vue 2 中是不可能的,因为:
- 子组件仅在数据加载后创建
- 父级需要知道条件何时更改(因此它需要访问实际条件)以便在呈现回退内容或子组件之间切换。
在 Vue 2 中最简单的方法实际上是在父组件中加载数据并将结果通过 props 传递给子组件。如果您有很多子组件,此模式可能会变得混乱。
在 Vue 3 中,加载数据和检查条件的责任完全由子组件承担。家长不需要了解实际情况。
就像 <template>
一样,<Suspense>
不会创建 DOM 元素。
在上面的Vue 3例子中,<RenderItems />
是挂起的。