Vue 3 中的可挂组件是什么? [英] What is a suspensible component in Vue 3?
问题描述
我正在阅读这篇文章:https://v3.vuejs.org/guide/component-dynamic-async.html#using-with-suspense
它指的是一个名为suspensible"的概念;组件.
我进行了研究,但找不到任何关于所谓可疑"的信息.组件.
谁能解释一下它是什么?谢谢!
Suspensible" 表示在父
解析 时可被后备内容替换在其
子组件. 中找到 async
该概念借鉴自 React 的 Suspense API.
更详细地说,
是一个内置的 Vue 3 组件,它呈现一个 而不是
<模板#default>
,直到默认模板中的所有async
子组件都被解析.
为了可挂起,组件的渲染需要依赖于一个promise:
- 使用
() => 加载import('some/path')
- 或在其
setup
函数中使用async/await
(或任何其他形式的 Promise 语法)
当包含在 <Suspense>
的默认模板中时,可挂起的组件是 挂起的,而其父
具有没有解析所有的挂起组件,即使挂起的组件本身已经解析.
显然,
组件本身是可悬置的,悬置可以嵌套.
这里有一个更详细的解释在 Vue 3 中的
.
在其他用法中,
提供了一种优雅而直观的方法来解决必须在 v-if
中包装子组件和模板的常见问题,以防止尚未加载的数据上不存在的属性.
典型的 Vue 2 示例:
Vue.config.devtools = false;Vue.config.productionTip = false;Vue.component('render-items', {道具:['物品'],模板:`<tr><th>Id</th><th>用户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>
`});新的 Vue({el: '#app',数据:() =>({项目: []}),计算:{有数据(){返回 this.items.length;}},异步创建(){const items = await fetch('https://jsonplaceholder.typicode.com/posts').then(r => r.json());this.items = 物品;}})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.12/vue.js"></script><div id="应用程序"><render-items :items="items" v-if="hasData"></render-items><template v-else>正在加载...</template>
Vue 3 中的相同示例(或多或少),使用
和 async setup
:
const RenderItems = Vue.defineComponent({异步设置(){const items = await fetch('https://jsonplaceholder.typicode.com/posts').then(r => r.json());返回 Vue.reactive({ items });},模板:`<tr><th>Id</th><th>用户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>
`});const App = { 组件:{ RenderItems }};Vue.createApp(App).mount('#app');
<script src="https://unpkg.com/vue@next/dist/vue.global.prod.js"></脚本><div id="应用程序"><悬念><模板#default><render-items></render-items></模板><模板#fallback>加载中...</模板></悬念>
一个主要优点是在 Vue 3 示例中,我们可以在子组件中包含数据获取器(和数据).这在 Vue 2 中是不可能的,因为:
- 子组件仅在数据加载后创建
- 父组件需要知道条件何时发生变化(因此它需要访问实际条件),以便在呈现后备内容或子组件之间切换.
在 Vue 2 中最简单的方法实际上是在父组件中加载数据并将结果通过 props 传递给子组件.如果您有很多子组件,则此模式可能会变得混乱.
在 Vue 3 中,加载数据和检查条件的责任完全由子组件承担.父级不需要访问实际情况.
就像 一样,
不会创建 DOM 元素.
在上面的 Vue 3 示例中,
是可挂起的.
I'm reading this article: https://v3.vuejs.org/guide/component-dynamic-async.html#using-with-suspense
It's referring a concept called "suspensible" component.
I have researched, but I can't find any information about what is a so called "suspensible" component.
Can anyone explain what it is? Thanks!
"Suspensible" means replaceable by fallback content while parent <Suspense>
resolves async
child components found in its <template #default>
.
The concept is borrowed from React's Suspense API.
In more detail, <Suspense>
is a built-in Vue 3 component which renders a <template #fallback>
instead of the <template #default>
, until all async
child components in default template are resolved.
In order to be suspensible, a component's rendering needs to depend on a promise:
- be loaded using
() => import('some/path')
- or use an
async/await
(or any other form of Promise syntax) in itssetup
function
A suspensible component is suspensed when included in a <Suspense>
's default template, while its parent <Suspense>
has not resolved all its suspensible components, even if the suspensed component itself has already resolved.
Obviously, <Suspense>
components themselves are suspensible and suspensing can be nested.
Here's a more detailed explanation on <Suspense>
in Vue 3.
Among other usages, <Suspence>
provides an elegant and intuitive way to resolve the common problem of having to wrap child components and templates in v-if
guarding against non-existent properties on data which has not yet been loaded.
A typical Vue 2 example:
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>
Same example (more or less) in Vue 3, using <Suspense>
and 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>
One major advantage is in the Vue 3 example we can contain the data fetcher (and the data) in the child component. This is not possible in Vue 2, because:
- the sub-component is only created after data has loaded
- the parent needs to know when the condition changed (so it needs access to the actual condition) in order to switch between rendering fallback content or the child component.
The simplest way to do it in Vue 2 is actually to load the data in parent and pass the result to the child component, via props. If you have a lot of sub-components, this pattern can get messy.
In Vue 3, the responsibility for loading the data and checking the condition can rest entirely with the child-component. Parent doesn't need access to the actual condition.
Just like <template>
, <Suspense>
does not create a DOM element.
In the above Vue 3 example, <RenderItems />
is suspensible.
这篇关于Vue 3 中的可挂组件是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!