您好,登錄后才能下訂單哦!
單頁應用其一個問題是首屏屏渲染速度較慢。這是因為頁面首次加載時服務器將向客戶端發送大量JavaScript,在屏幕上顯示任何內容之前必須下載并解析。可以想象,隨著應用程序規模的擴大,這個問題對用戶體驗的影響也會越來越突出。
現在幸運的是,當使用Vue CLI構建Vue應用程序時(使用webpack),可以采取一些措施來抵消這種情況。在本文中,我將演示如何在應用程序的初始渲染之后使用 異步組件
和webpack的代碼分割功能加載到頁面的某些部分。這將使初始加載時間降至最低,并為您的應用程序提供更好的用戶體驗。
認識異步組件
在我們開始創建異步組件之前,讓我們看一下我們通常如何加載組件。為此,我們將使用一個非常簡單的消息組件作為例子:
<!-- Message.vue --> <template> <h2>New message!</h2> </template>
現在我們已經創建了我們的 Message
組件,讓我們將它加載到我們的文件中并顯示它。我們可以導入組件并將其添加到組件選項中,以便我們可以在模板中使用它:
<!-- App.vue --> <template> <div> <message></message> </div> </template> <script> import Message from "./Message"; export default { components: { Message } }; </script>
但現在發生了什么?只要應用程序加載,就會加載 Message
組件,因此它包含在初始加載過程中。
對于一個簡單的應用程序來說,這看起來可能不是一個大問題,但可以考慮像電商網站這樣復雜的場景。想象一下,用戶將項目添加到購物車,然后想要結帳,因此單擊結帳按鈕會生成一個包含所選商品的所有詳細信息的框。使用上述方法,此結帳框將包含在初始包中,但我們只需在用戶單擊結帳按鈕時使用該組件。用戶甚至可以在不點擊結賬按鈕的情況下瀏覽網站,這意味著在加載這個可能不會使用的組件時浪費資源是沒有意義的。
為了提高應用程序的效率,我們可以結合延遲加載和代碼分割技術。
Webpack提供的代碼拆分功能允許您將代碼拆分為各種捆綁包,然后可以按需加載或稍后并行加載。它只能在需要或使用時加載特定的代碼片段。
Dynamic Imports(動態導入)
Vue使用Dynamic Imports解決這種情況。此功能引入了一種新的類似函數的導入形式,它將返回包含(Vue)組件的Promise。由于import是一個接收字符串的函數,我們可以做一些強大的事情,比如使用表達式加載模塊。自版本61以來,Chrome中已提供動態導入。有關這些內容的詳細信息, 請訪問Google Developers網站 。
代碼拆分由webpack,Rollup或Parcel等捆綁器處理,它們解析動態導入語法并為每個動態導入的模塊創建單獨的文件。稍后我們將在控制臺的網絡選項卡中看到這一點。但首先,我們來看看靜態和動態導入之間的區別:
// static import import Message from "./Message"; // dynamic import import("./Message").then(Message => { // Message module is available here... });
現在,讓我們將這些知識應用到我們的 Message
組件中,我們將得到一個如下所示的組件: App.vue
<!-- App.vue --> <template> <div> <message></message> </div> </template> <script> import Message from "./Message"; export default { components: { Message: () => import("./Message") } }; </script>
如你所見,函數import()將解析返回組件的Promise,這意味著我們已成功異步加載組件。如果您查看 devtools
的 network
選項卡,您會注意到一個名為 0.js
包含異步組件的文件。
根據條件加載異步組件
現在我們已經掌握了異步組件,讓我們僅在真正需要時加載它們。在本文的上一節中,我解釋了僅在用戶點擊結帳按鈕時才加載的結帳框的用例。讓我們把它構建出來。
項目設置
如果您沒有安裝 vue/cli
,首先應該安裝它:
npm i -g @vue/cli
接下來,使用CLI創建新項目,在出現提示時選擇默認預設即可:
vue create my-store
轉到項目目錄,然后安裝我們將用于樣式的ant-design-vue庫:
cd my-store npm i ant-design-vue
接下來,導入Ant設計庫: src/main.js
import 'ant-design-vue/dist/antd.css'
最后我們在 src/comonents
里創建兩個新組件 Checkout.vue
和 Items.vue
:
touch src/components/{Checkout.vue,Items.vue}
寫一個商店的視圖層
打開 src/App.vue
并用以下代碼替換文件里代碼:
<template> <div id="app"> <h2>{{ msg }}</h2> <items></items> </div> </template> <script> import items from "./components/Items" export default { components: { items }, name: 'app', data () { return { msg: 'My Fancy T-Shirt Store' } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } h2, h3 { font-weight: normal; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } </style>
這里沒有什么花哨的東西。我們所做的只是顯示一條消息并渲染一個 <items>
組件。
接下來,打開 src/components/Items.vue
并添加以下代碼:
<template> <div> <div > <Row :gutter="16"> <Col :span="24" > <Icon type="shopping-cart" />{{shoppingList.length}} item(s) <Button @click="show = true" id="checkout">Checkout</Button> </Col> </Row> </div> <div v-if="show"> <Row :gutter="16" > <checkout v-bind:shoppingList="shoppingList"></checkout> </Row> </div> <div > <Row :gutter="16"> <Col :span="6" v-for="(item, key) in items" v-bind:key="key" > <Card v-bind:title="item.msg" v-bind:key="key"> <Button type="primary" @click="addItem(key)">Buy ${{item.price}}</Button> </Card> </Col> </Row> </div> </div> </template> <script> import { Card, Col, Row, Button, Icon } from 'ant-design-vue'; export default { methods: { addItem (key) { if(!this.shoppingList.includes(key)) { this.shoppingList.push(key); } } }, components: { Card, Col, Row, Button, Icon, checkout: () => import('./Checkout') }, data: () => ({ items: [ { msg: 'First Product', price: 9.99 }, { msg: 'Second Product', price: 19.99 }, { msg: 'Third Product', price: 15.00 }, { msg: 'Fancy Shirt', price: 137.00 }, { msg: 'More Fancy', price: 109.99 }, { msg: 'Extreme', price: 3.00 }, { msg: 'Super Shirt', price: 109.99 }, { msg: 'Epic Shirt', price: 3.00 }, ], shoppingList: [], show: false }) } </script> <style> #checkout { background-color:#e55242; color:white; margin-left: 10px; } </style>
在此文件中,我們顯示一個帶有商品數量的購物車圖標。商品是從 items
數組中提取的。如果單擊項目的 Buy
按鈕,將會調用 addItem
方法,該方法會將相關商品push到 shoppingList
數組中。從而增加購物車的總數。
我們還在頁面中添加了一個 Checkout
按鈕:
<Button @click="show = true" id="checkout">Checkout</Button>
當用戶點擊這個按鈕,我們設置的參數 show
是 true
。 true
是非常重要對于有通過條件地加載我們的異步組件。
在接下來的幾行中,您可以找到 v-if
的聲明,這個語句僅用來顯示我們 checkout
組件的 <div>
,但是我們只想在用戶點擊 Checkout
按鈕時顯示結賬組件,我們該怎么辦?
這里我們將 checkout
組件在 components
選項里異步加載。這里 v-bind
將參數傳遞給組件。正如你看的的這樣,創建條件異步組件是很容易的:
<div v-if="show"> <checkout v-bind:shoppingList="shoppingList"></checkout> </div>
讓我們快速 Checkout
組件添加下面的代碼在 src/components/Checkout.vue
里:
<template> <Card title="Checkout Items" key="checkout"> <p v-for="(k, i) in this.shoppingList" :key="i"> Item: {{items[Number(k)].msg}} for ${{items[Number(k)].price}} </p> </Card> </template> <script> import { Card } from 'ant-design-vue'; export default { props: ['shoppingList'], components: { Card }, data: () => ({ items: [ { msg: 'First Product', price: 9.99 }, { msg: 'Second Product', price: 19.99 }, { msg: 'Third Product', price: 15.00 }, { msg: 'Fancy Shirt', price: 137.00 }, { msg: 'More Fancy', price: 109.99 }, { msg: 'Extreme', price: 3.00 }, { msg: 'Super Shirt', price: 109.99 }, { msg: 'Epic Shirt', price: 3.00 }, ] }) } </script>
在這里,我們將接收一個 shoppingList
并把他輸出到屏幕上。
您可以使用該 npm run serve
命令運行該應用程序。然后導航到 http:// localhost:8080
。如果一切按計劃進行,你應該會看到如下圖所示的內容。
可以嘗試打開在 network
選項卡,點擊Checkout按鈕,可以發現 network
里將異步加載 結賬組件
。
您還可以在GitHub上查看此演示的代碼 。
為異步組件添加加載中和加載錯誤組件
有時異步組件加載過長或加載時。顯示加載動畫或錯誤信息可能很有用,但要支持這會再次降低應用程序的速度。異步組件應該小而且加載速度快。這是一個例子:
const Message = () => ({ component: import("./Message"), loading: LoadingAnimation, error: ErrorComponent });
總結
創建和實現異步組件非常簡單,應該成為標準開發例程的一部分。從用戶體驗的角度來看,盡可能減少初始加載時間以保持用戶的注意力是非常重要。希望本教程可以幫助您構建異步加載組件。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。