1. 程式人生 > 其它 >vue3 新增內建元件Suspense、Teleport

vue3 新增內建元件Suspense、Teleport

1、非同步請求元件 Suspense
Suspense是Vue3推出的一個內建的特殊元件,有兩個template slot,剛開始會渲染一個fallback內容,直到達到某個條件以後才會渲染正式的內容。
如果使用Suspense,在setup( )中需要返回一個promise,而不是直接返回一個物件。
Async1.vue

<template>
  <h1>{{result}}</h1>
</template>

<script>
import { defineComponent }  from "vue";
export
default defineComponent({ setup() { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ result: "非同步元件" }); }, 2000) }) } }) </script>

使用時

<template>
  <div>
    <Suspense>
      <template #default
> <async-one /> </template> <template #fallback> <h1>Loading...</h1> </template> </Suspense> </div> </template> <script> import AsyncOne from '../../components/Async1.vue' export default { name: "suspense"
, components:{ AsyncOne } } </script>

Suspense 中可以新增多個非同步元件,template default包裹多個元件,等這些個result都載入好了一起進行展示。

<template>
  <div>
    <Suspense>
      <template #default>
        <div>
          <async-one />
          <async-two />
        </div>
      </template>
      <template #fallback>
        <h1>Loading...</h1>
      </template>
    </Suspense>
  </div>
</template>

<script>
import AsyncOne from '../../components/Async1.vue'
import AsyncTwo from '../../components/Async2.vue'

export default {
  name: "suspense",
  components:{
    AsyncOne,
    AsyncTwo
  }
}
</script>

非同步請求錯誤處理onErrorCaptured
在非同步請求中必須要作的一件事情,就是要捕獲錯誤,因為我們沒辦法後端給我們返回的結果,也有可能服務不通,所以一定要進行捕獲異常和進行處理。
在vue3.x的版本中,可以使用onErrorCaptured這個鉤子函式來捕獲異常,鉤子函式要求我們返回一個布林值,代表錯誤是否向上傳遞
Async.vue

<template>
  <h1>{{result}}</h1>
</template>

<script>
import { defineComponent }  from "vue";
export default defineComponent({
  setup() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        reject({
          result: "非同步元件"
        });
      }, 2000)
    })
  }
})
</script>
<template>
  <div>
    <Suspense>
      <template #default>
        <async-one />
      </template>
      <template #fallback>
        <h1>Loading...</h1>
      </template>
    </Suspense>
  </div>
</template>

<script>
import { onErrorCaptured } from "vue";
import AsyncOne from '../../components/Async1.vue'

export default {
  name: "suspense",
  components:{
    AsyncOne
  },
  setup() {
    onErrorCaptured((error) => {
      console.log(error);
      return true;
    })

    return {};
  }
}
</script>

在這裡插入圖片描述

2、Teleport
Teleport 是一種能夠將我們的模板移動到 DOM 中 Vue app 之外的其他位置的技術
如果我們巢狀在 Vue 的某個元件內部,那麼處理巢狀元件的定位、z-index 和樣式就會變得很困難。
使用Teleport 就可以方便的解決元件間 css 層級問題
要使用teleport,首先要在頁面上新增一個元素,我們要將模態內容移動到該頁面

<!-- index.html -->
<body>
  <div id="app"></div>
  <div id="modal-container"></div>
</body>

我們將模態內容包裝在 teleport 元件中,還需要指定一個 to 屬性,以標識目標元素,此處為#modal-container

<template>
  <div>
    <teleport to="#modal-container" v-if="show">
      <div class="modal-container">
         彈窗內容
      </div>
    </teleport>
    <van-button type="primary" @click="openDialog">彈窗</van-button>
  </div>
</template>

<script>
import {
  ref
} from "vue"
export default {
  name: 'teleport',
  setup() {
    const show = ref(false);

    const openDialog = () => {
      show.value = true;

      setTimeout(() => { // 彈窗的顯示時常
        show.value = false;
      }, 1500)
    }

    return {
      show,
      openDialog
    }
  }
}
</script>

<style scoped>
.modal-container {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 10px 20px;
  background: black;
  border-radius: 40px;
  opacity: 0.7;
  color: white;
  font: normal 16px/20px arial;
}
</style>

在同一目標上使用多個teleport

<template>
  <div>
    <teleport to="#modal-container" v-if="show">
      <div class="modal-container">
         彈窗內容
      </div>
    </teleport>
    <teleport to="#modal-container" v-if="show">
      <div class="modal-container">
         彈窗內容2
      </div>
    </teleport>
    <van-button type="primary" @click="openDialog">彈窗</van-button>
  </div>
</template>

對於這種情況,多個teleport元件可以將其內容掛載到同一個目標元素。順序將是一個簡單的追加——稍後掛載將位於目標元素中較早的掛載之後

原始碼:https://gitee.com/smallgrey/new-features-of-vue3
微信公眾號:趣享程式設計