Vue動態(tài)組件與異步組件實例詳解
本文實例講述了Vue動態(tài)組件與異步組件。分享給大家供大家參考,具體如下:
1 在動態(tài)組件上使用 keep-alive
我們之前曾經在一個多標簽的界面中使用 is 特性來切換不同的組件:
<component v-bind:is="currentTabComponent"></component>
當在這些組件之間切換的時候,你有時會想保持這些組件的狀態(tài),以避免反復重渲染導致的性能問題。例如我們來展開說一說這個多標簽界面:

你會注意到,如果你選擇了一篇文章,切換到 Archive 標簽,然后再切換回 Posts,是不會繼續(xù)展示你之前選擇的文章的。這是因為你每次切換新標簽的時候,Vue 都創(chuàng)建了一個新的 currentTabComponent 實例。
重新創(chuàng)建動態(tài)組件的行為通常是非常有用的,但是在這個案例中,我們更希望那些標簽的組件實例能夠被在它們第一次被創(chuàng)建的時候緩存下來。為了解決這個問題,我們可以用一個 <keep-alive> 元素將其動態(tài)組件包裹起來。
<!-- 失活的組件將會被緩存!--> <keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive>
現(xiàn)在這個 Posts 標簽保持了它的狀態(tài) (被選中的文章) 甚至當它未被渲染時也是如此。
html:
<div id="dynamic-component-demo">
<button
v-for="tab in tabs"
v-bind:key="tab"
v-bind:class="['tab-button',{active:currentTab === tab}]"
v-on:click="currentTab = tab"
>{{ tab }}
</button>
<keep-alive>
<component
v-bind:is="currentTabComponent"
class="tab"></component>
</keep-alive>
</div>
js:
Vue.component('tab-posts', {
data: function () {
return {
posts: [
{
id: 1,
title: '趕在618前夕,微信更新了兩個支付與電商功能',
content: '本周末,中國消費者即將迎來上半年最大的消費網購峰值,6月17日父親節(jié),6月18日端午節(jié),也是京東、天貓等電商的618購物節(jié)。略微出人意料但又在情理之中的是,中國最大的社交平臺微信,近日密集上線了兩個與支付和電商相關的功能。'
},
{
id: 2,
title: '騰訊要花32億收購《絕地求生》開發(fā)商10%股份',
content: '目前騰訊和藍洞已經接近達成協(xié)議,如果交易成功,騰訊將成為藍洞的第二大股東。'
},
{
id: 3,
title: '這兩個地球之眼是真的嗎?形成原因至今仍是謎團',
content: '一名俄羅斯男子乘坐直升機游覽時,經過俄羅斯薩哈林島(庫頁島)時,看到一個巨大的坑洞。地球上坑坑洞洞很多,本該不用大驚小怪。但當飛機離得更近,換了個角度看這個坑時,他震驚了,這分明就是“地球的眼睛”。'
}
],
selectedPost: null
}
},
template: `
<div class="posts-tab">
<ul class="posts-sidebar">
<li
v-for="post in posts"
v-bind:key="post.id"
v-bind:class="{selected:post === selectedPost}"
v-on:click="selectedPost = post">
{{ post.title }}
</li>
</ul>
<div class="selected-post-container">
<div
v-if="selectedPost"
class="selected-post">
<h3>{{ selectedPost.title }}</h3>
<div v-html="selectedPost.content"></div>
</div>
<strong v-else>
請點擊某個標簽頁
</strong>
</div>
</div>
`
});
Vue.component('tab-archive', {
template: '<div>archive 頁面</div>'
});
new Vue({
el: '#dynamic-component-demo',
data: {
currentTab: 'Posts',
tabs: ['Posts', 'Archive']
},
computed: {
currentTabComponent: function () {
return 'tab-' + this.currentTab.toLowerCase();
}
}
});
css:
.tab-button {
padding: 6px 10px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border: 1px solid #ccc;
cursor: pointer;
background: #f0f0f0;
margin-bottom: -1px;
margin-right: -1px;
}
.tab-button:hover {
background: #e0e0e0;
}
.tab-button.active {
background: #e0e0e0;
}
.tab {
border: 1px solid #ccc;
padding: 10px;
}
.posts-tab {
display: flex;
}
.posts-sidebar {
max-width: 40vw;
margin: 0;
padding: 0 10px 0 0;
list-style-type: none;
border-right: 1px solid #ccc;
}
.posts-sidebar li {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
cursor: pointer;
}
.posts-sidebar li:hover {
background: #eee;
}
.posts-sidebar li.selected {
background: lightblue;
}
.selected-post-container {
padding-left: 10px;
}
.selected-post > :first-child {
margin-top: 0;
padding-top: 0;
}
效果:

2 異步組件
在大型應用中,我們可能需要將應用分割成小一些的代碼塊,并且只在需要的時候才從服務器加載一個模塊。為了簡化,Vue 允許你以一個工廠函數(shù)的方式定義你的組件,這個工廠函數(shù)會異步解析你的組件定義。Vue 只有在這個組件需要被渲染的時候才會被觸發(fā),且會把結果緩存起來供未來重渲染。例如:
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
//在此定義組件
resolve({
template: `
<div>
我是異步加載的哦
</div>
`
})
}, 1000);
});
如你所見,這個工廠函數(shù)會收到一個 resolve 回調,這個回調函數(shù)會在你從服務器得到組件定義的時候被調用。你也可以調用 reject(reason) 來表示加載失敗。這里的 setTimeout 是為了演示用的,如何獲取組件取決于你自己。一個推薦的做法是將異步組件和 webpack 的 code-splitting 功能 一起配合使用:
Vue.component('async-webpack-example', function (resolve) {
// 這個特殊的 `require` 語法將會告訴 webpack
// 自動將你的構建代碼切割成多個包,這些包
// 會通過 Ajax 請求加載
require(['./my-async-component'], resolve)
})
你也可以在工廠函數(shù)中返回一個 Promise,所以把 webpack 2 和 ES2015 語法加在一起,我們可以寫成這樣:
Vue.component(
'async-webpack-example',
// 這個 `import` 函數(shù)會返回一個 `Promise` 對象。
() => import('./my-async-component')
)
當使用局部注冊的時候,你也可以直接提供一個返回 Promise 的函數(shù):
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
如果你是一個 Browserify 用戶同時喜歡使用異步組件,很不幸這個工具的作者明確表示異步加載“并不會被 Browserify 支持”,至少官方不會。Browserify 社區(qū)已經找到了一些變通方案,這些方案可能會對已存在的復雜應用有幫助。對于其它的場景,我們推薦直接使用 webpack,以擁有內建的被作為第一公民的異步支持。
處理加載狀態(tài)
2.3.0+ 新增
這里的異步組件工廠函數(shù)也可以返回一個如下格式的對象:
const AsyncComponent = () => ({
// 需要加載的組件 (應該是一個 `Promise` 對象)
component: import('./MyComponent.vue'),
// 異步組件加載時使用的組件
loading: LoadingComponent,
// 加載失敗時使用的組件
error: ErrorComponent,
// 展示加載時組件的延時時間。默認值是 200 (毫秒)
delay: 200,
// 如果提供了超時時間且組件加載也超時了,
// 則使用加載失敗時使用的組件。默認值是:`Infinity`
timeout: 3000
})
注意如果你希望在 Vue Router 的路由組件中使用上述語法的話,你必須使用 Vue Router 2.4.0+ 版本。
希望本文所述對大家vue.js程序設計有所幫助。
相關文章
vue+flv.js+SpringBoot+websocket實現(xiàn)視頻監(jiān)控與回放功能
vue+springboot的項目,需要在頁面展示出??档挠脖P錄像機連接的攝像頭的實時監(jiān)控畫面以及回放功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2022-02-02
elementUI給el-tabs/el-tab-pane添加圖標效果實例
這篇文章主要給大家介紹了關于elementUI給el-tabs/el-tab-pane添加圖標效果實例的相關資料,文中通過實例代碼介紹的非常詳細,對大家學習或者使用elementUI具有一定的參考學習價值,需要的朋友可以參考下2023-07-07
vue單行文本溢出會出現(xiàn)title提示自定義指令
這篇文章主要為大家介紹了vue單行文本溢出會出現(xiàn)title提示自定義指令,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01

