首頁  >  文章  >  web前端  >  快速了解Vue3中的Fragment、Suspense、Portal特性

快速了解Vue3中的Fragment、Suspense、Portal特性

青灯夜游
青灯夜游轉載
2022-01-18 19:36:075461瀏覽

這篇文章帶大家了解Vue3中的3個新特性Fragment(碎片化節點)、Suspense(非同步組件)、Portal(傳送門),希望對大家有幫助。

快速了解Vue3中的Fragment、Suspense、Portal特性

vue3中新增了一些功能來解決vue2中那些戳中開發人員痛楚的詬病。同時,也對vue2中效能進行了最佳化。本文帶你一起探討vue3中新增的FragmentTeleportSuspense的使用方法。

Fragment(碎片化節點)

不知道各位有沒有在vue2中遇到過下圖中的報錯資訊:

快速了解Vue3中的Fragment、Suspense、Portal特性

這是vue2拋出的錯誤提示。意思是說元件只能有一個根元素。當我們新建一個vue頁面時,通常會有多個不同的元素節點。我們會在最外層包裹一個div來使其讓它成為這個頁面的根節點。但這並不友善。有時候我們並不需要這個div元素。

vue3中解決了這個問題。 vue3中新增了一個類似dom的標籤元素<fragment></fragment>。如果在vue頁面中有多個元素節點。那麼編譯時vue會在這些元素節點上加上一個<fragment></fragment>標籤。且該標籤不會出現在dom樹中。

快速了解Vue3中的Fragment、Suspense、Portal特性

Suspense(非同步元件)

vue3中提供一個<suspense></suspense>組件用於控制非同步組件。

//创建一个异步组件
<script>
const { createApp,defineAsyncComponent } = Vue
const app = createApp({})
const AsyncComp = defineAsyncComponent(
    () =>
        new Promise((resolve, reject) => {
          setTimeout(() => resolve({
            template: &#39;<div>I am async!</div>&#39;
          }),3000)
        })
)
app.component(&#39;async-component&#39;, AsyncComp)
app.mount(&#39;#app&#39;)
</script>

Suspense包裹非同步元件async-component

<Suspense>
    <template #default>
      <async-component />
    </template>
    <template #fallback>
      Loading ...
    </template>
  </Suspense>

上面的非同步元件使用了定時器,3秒後顯示該元件我們可以透過defineAsyncComponent提供一系列的參數來定義非同步元件

import { defineAsyncComponent } from &#39;vue&#39;

const AsyncComp = defineAsyncComponent({
  // 工厂函数
  loader: () => import(&#39;./Foo.vue&#39;),
  // 加载异步组件时要使用的组件
  loadingComponent: LoadingComponent,
  // 加载失败时要使用的组件
  errorComponent: ErrorComponent,
  // 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms)
  delay: 200,
  // 如果提供了 timeout ,并且加载组件的时间超过了设定值,将显示错误组件
  // 默认值:Infinity(即永不超时,单位 ms)
  timeout: 3000,
  // 定义组件是否可挂起 | 默认值:true
  suspensible: false,
  /**
   *
   * @param {*} error 错误信息对象
   * @param {*} retry 一个函数,用于指示当 promise 加载器 reject 时,加载器是否应该重试
   * @param {*} fail  一个函数,指示加载程序结束退出
   * @param {*} attempts 允许的最大重试次数
   */
  onError(error, retry, fail, attempts) {
    if (error.message.match(/fetch/) && attempts <= 3) {
      // 请求发生错误时重试,最多可尝试 3 次
      retry()
    } else {
      // 注意,retry/fail 就像 promise 的 resolve/reject 一样:
      // 必须调用其中一个才能继续错误处理。
      fail()
    }
  }
})

當設定項中的suspensible為true時,被Suspense#包裹的非同步元件將會被控制

Portal(傳送門)

在vue2中我們可能會使用例如element-ui,iview等元件庫,有時候我們會發現這些ui元件庫中的某些元件渲染層級並不包含在vue dom中。如 modal toast等元件的層級就在vue dom 之外。這種在vue之外的層級方便我們進行全域處理和管理。 vue3中提供一對<teleport></teleport>用於移動dom的層級

<div id="app">
  <h1>Hello Async Component</h1>
  <com-a />
</div>
<div class="i-can-fly"></div>
// 组件a
const { createApp } = Vue
const componentA = {
 template: `<com-b><com-b/><div class="i-can-fly">我能瞬间移动</div>`
 }
const componentB ={
template: `<div class="i-can-fly">我能飞</div>`
}
const app = createApp({})
app.component(&#39;com-b&#39;,componentB)
app.component(&#39;com-a&#39;,componentA)
app.mount(&#39;#app&#39;)

此時我們打開控制台查看元素

快速了解Vue3中的Fragment、Suspense、Portal特性

#渲染的結果如下。然後我們修改程式碼加入teleport標籤

<div id="app">
   <----...--->
  <teleport to=".i-can-fly">
    <com-a />
  </teleport>
</div>
<div class="i-can-fly"></div>

此時我們發現元件B已經不在app中了。而是出現在了以類別選擇器為i-can-fly的div中。

快速了解Vue3中的Fragment、Suspense、Portal特性

值得注意的是 teleport標籤上的to參數表示要將包裹的內容移動到的位置。

【相關推薦:vue.js教學

以上是快速了解Vue3中的Fragment、Suspense、Portal特性的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除