Vue中的異步組件

特別聲明,本文根據@Alex Jover Morales的《Async Vue.js Components》一文所整理。html

隨着應用程序愈來愈大,你開始考慮優化應用程序,使其變得更快。在此過程當中,你可能使用了拆分代碼和延遲加載這兩種方法,它們經過將代碼塊的加截推遲到須要的時候加載,從而使應用程序的初始包變得更小。vue

延遲加載對於應用程序路由有很大的意義,而且有很大的影響,由於每一個路由都是應用程序的不一樣部分。webpack

延遲加載有意義的另外一種狀況是組件延遲渲染。這些組件能夠是tooltipspopovermodal等,固然這些組件也可使用異步組件git

讓咱們來看看如何在Vue中構建延遲加載異步組件。github

延遲加載組件

在咱們開始瞭解延遲加載組件以前,咱們先來了解一般是如何加載組件的。 爲此,我建立了一個Tooltip.vue組件:web

<!-- Tooltip.vue -->
<template> <h1>Hi from Tooltip!</h2> </template>
複製代碼

這裏沒有什麼特別之處,它就是一個簡單的組件。咱們能夠經過本地註冊,導入Tooltip組件並將其添加到components選項中,這樣就能夠在另外一個組件中使用它。好比,在App.vue中使用它:vue-cli

<!-- App.vue -->
<template> <div id="app"> <Tooltip /> </div> </template>

<script>
    import Tooltip from "./components/Tooltip"

    export default {
        name: "App",
        components: {
            Tooltip
        }
    };
</script>
複製代碼

只要App被導入,就能夠在初始加載時,Tooltip組件就會被導入、使用和加載。可是想一想:只有在咱們要使用組件時才加載該組件難道沒有意義嗎?用戶極可能在不須要工具提示的狀況下瀏覽整個系統。緩存

爲何咱們要在應用程序開始時花費寶貴的資源來加載組件呢?咱們能夠應用延遲加載和代碼拆分來改進它。延遲加載是在稍後的階段加載某些內容的技術。bash

雖然代碼拆分是將一段代碼拆分到一個單獨的文件(稱爲chunk)中,以便減小應用程序的初始包,從而減輕初始加載。網絡

經過使用動態導入(Dynamic import,Vue能夠輕鬆應用這些技術。在ES2018中也會具備這樣的功能,它容許程序在運行時加載模塊。我閃將有一篇文章深刻探討這些概念,但讓咱們從實用和簡單的角度開始吧。

現代的綁定器(Modern bundlers),好比Webpack(從版本2開始),RollupParcel將理解這種語法並自動爲該模塊建立一個單獨的文件,該文件將在須要時加載。

我在這裏認爲你已經熟悉了靜態方式導入模塊。然而,動態導入是一個返回Promise的函數,其中包含模塊做爲其有效的加載。下面的示例展現瞭如何以靜態導入和動態方式導入utils模塊。

// 靜態導入模塊
import utils from './utils'
複製代碼
// 動態導入
import('./utils').then(utils => {
    // 能夠在這裏使用utils模塊
})
複製代碼

在Vue中延遲加載組件與在封裝的函數中動態導入組件同樣容易。在前面的例子中,咱們能夠像下面這樣延遲加載Tooltip組件:

export default {
    components: {
        Tooltip: () => import('./components/Tooltip')
    }
}
複製代碼

使用**() => import('./components/Tooltip')替代前面示例中的import Tooltip from "./components/Tooltip"**。Vue一旦請求渲染將會延遲加載該組件。

不只如此,它還將應用代碼拆分。你可使用上面提到的任何綁定器運行代碼來進行測試。最簡單的方式就是使用vue-cil,但在文章的最後,你將找到一個已經構建好的Demo。運行後,打開開發者工具,在Network一欄將可能夠看到一個名爲1.chunk.js這樣的JavaScript文件。

在這裏插入圖片描述

有條件地加載一個異步組件

在前面的示例中,儘管咱們經過延遲加載來加載Tooltip組件,但它將在須要渲染時當即加載,這在App組件加載時就當即發生了。

然而,在實踐中,咱們但願將Tooltip組件加載能延遲到須要時加載,這一般是在觸發某個事件以後有條件地進行,好比在按鈕或文本上懸停時觸發。

爲了簡單起見,在App組件中添加一個按鈕,使用v-if有條件地渲染Tooltip組件:

<!-- App.vue -->
<template>
    <div>
        <button @click="show = true">Load Tooltip</button>
        <div v-if="show">
            <Tooltip />
        </div>
    </div>
</template>

<script>
    export default {
        data: () => ({
            show: false
        }),

        components: {
            Tooltip: () => import('./components/Tooltip')
        }
    }
</script>
複製代碼

請記住,Vue在須要渲染以前不會使用該組件。這意味着在點擊以前不須要該組件,而且該組件將被延遲加載。

Edit Async Vue Components

異步組件的用戶體驗

大多數狀況下,異步組件加載速度很是快,由於它們是從主包中拆分出來的小塊代碼。可是想象一下,你在一個很是慢的網絡環境下緩慢的加載一個大的模態(Modal)組件。這可能須要一些時間來加載和渲染。

固然,你可使用一些優化,好比HTTP緩存或資源提示,以低優先級預加載到內存中。事實上,新的vue-cli會對這些延遲加載的塊預先獲取。不過,在一些狀況下,加載可能須要一些時間。

從用戶體驗的角度來看,若是一個任務須要超過1s的時間,你就會開始失去用戶的注意力。

可是,能夠經過向用戶提供反饋來保持注意力。爲了吸引用戶的注意力,咱們能夠在加載時使用progress(進度條)組件,可是在異步加載時,咱們如何使用一個漂亮的loadingprogress組件呢?

加載組件 你還記得咱們使用一個帶有動態導入的函數來延遲加載異步組件嗎?

export default {
    components: {
        Tooltip: () => import('./components/Tooltip')
    }
}
複製代碼

經過返回對象而不是動態導入的結果來定義異步組件長期的方法。在該對象中,咱們能夠定個一個加載組件:

const Tooltip = () => ({
    component: import('./components/Tooltip'),
    loading: AwesomeSpinner
})
複製代碼

這樣,在默認延遲200ms以後,組件AwesomeSpinner就會顯示出來。你也能夠自定義延遲時間:

const Tooltip = () => ({
    component: import('./components/Tooltip'),
    loading: AwesomeSpinner,
    delay: 500
})
複製代碼

做爲加載組件應該使用的組件必須儘量的小,以使它幾乎能當即加載

錯誤組件

一樣的,咱們能夠用延遲加載組件的方式來定義一個錯誤組件:

const Tooltip = () => ({
    component: import('./components/Tooltip'),
    loading: AwesomeSpinner,
    error: SadFaceComponent
})
複製代碼

加載**./components/Tooltip**組件出錯時,SadFaceComponent組件將會顯示。在下面這幾種狀況之下可能會發生這種狀況:

網絡癱瘓(連不上網) 該組件不存在(這是一種嘗試它的好方法,你能夠本身故意刪除它) 加載超時 默認狀況下,沒有超時,但咱們能夠本身配置:

const Tooltip = () => ({
    component: import('./components/Tooltip'),
    loading: AwesomeSpinner,
    error: SadFaceComponent,
    timeout: 5000
})
複製代碼

如今,若是在5000ms以後Tooltip組件還未加載,將會顯示SadFaceComponent組件。

總結

你已經瞭解瞭如何在本身的塊文件中分割組件,以及如何使用動態導入來延遲加載組件。咱們還經過有條件地渲染數據來延遲數據塊的加載。

雖然異步組件能夠經過分割和延遲的加載方式來提升應用程序的加載時間,但它們可能會對用戶體驗有很大的影響,尤爲是當它們很大的時候。控制加載狀態容許咱們提供反饋,並在速度很慢的狀況下讓用戶參與進來。


轉載聲明:
	做者:Alex Jover Morales
	連接:https://www.w3cplus.com/vue/async-vuejs-components.html © w3cplus.com
	來源:w3cplus
	聲明:著做權歸做者全部,謝絕商業轉載。如需轉載請聯繫原做者或者按照其原文聲明進行操做。
	承諾:本站除原創之外全部的轉載內容均是得到其做者受權或者聲明可轉載的。並只是將其做爲學習和交流目的,杜絕一切商業盈利行爲。如若侵權,請聯繫咱們刪除。
複製代碼

來源:91Code

關注公衆號獲取更多內容!

在這裏插入圖片描述
相關文章
相關標籤/搜索