淺談Vue.js組件(二)
插槽(Slot)
定義一個(gè)名child子組件,為該子組件添加內(nèi)容應(yīng)該在子組件的template中定義,直接在父組件的<child>標(biāo)簽中定義的內(nèi)容不會(huì)被渲染。
在子組件中通過加入<slot>元素占位,便能夠渲染父組件中子組件標(biāo)簽中的內(nèi)容了。
插槽內(nèi)容
- 任何模版代碼
- HTML代碼
- 其他組件
插槽可以有默認(rèn)內(nèi)容,當(dāng)在父組件中沒有提供內(nèi)容的時(shí)候,來進(jìn)行顯示。
<!-- submit-button --> <button type="submit"> <slot>Submit</slot> </button> 1. <submit-button></submit-button> ⬇️ <button type="submit"> Submit </button> 2. <submit-button> Save </submit-button> ⬇️ <button type="submit"> Save </button>
作用域
父級(jí)模板里的所有內(nèi)容都是在父級(jí)作用域中編譯的;子模板里的所有內(nèi)容都是在子作用域中編譯的。
具名插槽
試想,我們有一個(gè)帶有如下模版的<base-layout>組件
<div class="container"> <header> <!-- 我們希望把頁頭放這里 --> </header> <main> <!-- 我們希望把主要內(nèi)容放這里 --> </main> <footer> <!-- 我們希望把頁腳放這里 --> </footer> </div>
可以看到,在組件中顯示的內(nèi)容是劃分不同的部位的,這個(gè)時(shí)候就需要使用到<slot>元素的一個(gè)特有的屬性:name來實(shí)現(xiàn)了。這個(gè)特性可以用來定義額外的插槽。
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
一個(gè)不帶 name 的 <slot> 出口會(huì)帶有隱含的名字“default”。
在向具名插槽提供內(nèi)容的時(shí)候,我們可以在一個(gè) <template> 元素上使用 v-slot 指令,并以 v-slot 的參數(shù)的形式提供其名稱:
<base-layout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template v-slot:footer> <p>Here's some contact info</p> </template> </base-layout>
現(xiàn)在 <template> 元素中的所有內(nèi)容都將會(huì)被傳入相應(yīng)的插槽。任何沒有被包裹在帶有 v-slot 的 <template> 中的內(nèi)容都會(huì)被視為默認(rèn)插槽的內(nèi)容。
當(dāng)然,也可以將默認(rèn)插槽的內(nèi)容通過v-slot:default包裹起來。
v-slot 只能添加在一個(gè) <template> 上
作用域插槽
當(dāng)我們希望能夠讓插槽內(nèi)容能夠訪問子組件中才有的數(shù)據(jù)時(shí),我們可以將數(shù)據(jù)作為一個(gè)<slot>元素的特性綁定上去
<span> <slot v-bind:user="user"> {{ user.name }} </slot> </span>
綁定在<slot>元素上的特性被稱為插槽prop。此時(shí)我們?cè)诟附M件中通過給v-slot帶一個(gè)值來定義我們提供的插槽prop的名字。
<current-user> <template v-slot:default="slotProps"> {{ slotProps.user.age }} </template> </current-user>
獨(dú)占默認(rèn)插槽的縮寫語法
當(dāng)被提供的內(nèi)容只有默認(rèn)插槽時(shí),上面的寫法可以被簡化來寫
<!-- 簡化版 --> <current-user v-slot:default="slotProps"> {{ slotProps.user.firstName }} </current-user> <!-- 終極簡化版 --> <current-user v-slot="slotProps"> {{ slotProps.user.firstName }} </current-user>
需要注意兩點(diǎn):
- 簡化寫法不能和具名插槽混用,作用域不明確
- 出現(xiàn)多個(gè)插槽時(shí),所有插槽都使用完整的基于<template>語法
解構(gòu)插槽Prop
作用域插槽的內(nèi)部工作原理是將你的插槽內(nèi)容包括在一個(gè)傳入單個(gè)參數(shù)的函數(shù)里:
function (slotProps) { // 插槽內(nèi)容 }
這意味著 v-slot 的值實(shí)際上可以是任何能夠作為函數(shù)定義中的參數(shù)的 JavaScript 表達(dá)式。所以在支持的環(huán)境下 (單文件組件或現(xiàn)代瀏覽器),你也可以使用 ES2015 解構(gòu)來傳入具體的插槽 prop,如下:
<current-user v-slot:default="slotProps"> {{ slotProps.user.firstName }} </current-user> ⬇️ <current-user v-slot="{ user }"> {{ user.firstName }} </current-user>
使用場景舉例
插槽 prop 允許我們將插槽轉(zhuǎn)換為可復(fù)用的模板,這些模板可以基于輸入的 prop 渲染出不同的內(nèi)容。
這在設(shè)計(jì)封裝數(shù)據(jù)邏輯同時(shí)允許父級(jí)組件自定義部分布局的可復(fù)用組件時(shí)是最有用的。
動(dòng)態(tài)插槽名
動(dòng)態(tài)指令參數(shù)也可以用在 v-slot 上,來定義動(dòng)態(tài)的插槽名
<base-layout> <template v-slot:[dynamicSlotName]> ... </template> </base-layout>
具名插槽縮寫
v-slot可以縮寫為#。
縮寫方式只有在有參數(shù)的時(shí)候才可以使用
<!-- 這樣會(huì)觸發(fā)一個(gè)警告 --> <current-user #="{ user }"> {{ user.firstName }} </current-user> <!-- 這樣是正確的 --> <current-user #default="{ user }"> {{ user.firstName }} </current-user>
動(dòng)態(tài)組件&keep-alive
當(dāng)在這些組件之間切換的時(shí)候,你有時(shí)會(huì)想保持這些組件的狀態(tài),以避免反復(fù)重渲染導(dǎo)致的性能問題。為了解決這個(gè)問題,我們可以用一個(gè)<keep-alive>元素將動(dòng)態(tài)組件包裹起來
<!-- 失活的組件將會(huì)被緩存!--> <keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive>
注意這個(gè) <keep-alive> 要求被切換到的組件都有自己的名字,不論是通過組件的 name 選項(xiàng)還是局部/全局注冊(cè)。
更加詳細(xì)的說明在我們之后的實(shí)戰(zhàn)過程中遇到的話,再進(jìn)行專門解說。
異步組件
在實(shí)際的項(xiàng)目過程中,我們往往會(huì)將一系列的功能分割成一個(gè)個(gè)小的代碼塊,希望只有在需要的時(shí)候才去加載。為了達(dá)成這個(gè)目的,Vue允許我們以一個(gè)工廠函數(shù)的方式定義我們的組件,這個(gè)工廠函數(shù)會(huì)異步解析組件的定義。
Vue只有在這個(gè)組件需要渲染的時(shí)候才會(huì)觸發(fā)這個(gè)工廠函數(shù),而且會(huì)把結(jié)果緩存起來供之后使用。
Vue.component('async-example', function (resolve, reject) { setTimeout(function () { // 向 `resolve` 回調(diào)傳遞組件定義 resolve({ template: '<div>I am async!</div>' }) }, 1000) })
其實(shí),這個(gè)過程有些類似于我們?cè)O(shè)計(jì)一個(gè)異步函數(shù),這個(gè)工廠函數(shù)會(huì)收到一個(gè)resolve回調(diào),這個(gè)回調(diào)在我們從服務(wù)器獲取到組件定義的時(shí)候被調(diào)用,當(dāng)加載失敗的時(shí)候我們也可以調(diào)用reject(reason)。
一個(gè)推薦的做法是異步組件和webpack的code-splitting功能結(jié)合使用
Vue.component('async-webpack-example', function (resolve) { // 這個(gè)特殊的 `require` 語法將會(huì)告訴 webpack // 自動(dòng)將你的構(gòu)建代碼切割成多個(gè)包,這些包 // 會(huì)通過 Ajax 請(qǐng)求加載 require(['./my-async-component'], resolve) })
同樣,也可以在工廠函數(shù)中返回一個(gè)Promise
Vue.component( 'async-webpack-example', // 這個(gè) `import` 函數(shù)會(huì)返回一個(gè) `Promise` 對(duì)象。 () => import('./my-async-component') )
處理加載狀態(tài)
上面的工廠函數(shù)可以返回一個(gè)下面格式的對(duì)象
const AsyncComponent = () => ({ // 需要加載的組件 (應(yīng)該是一個(gè) `Promise` 對(duì)象) component: import('./MyComponent.vue'), // 異步組件加載時(shí)使用的組件 loading: LoadingComponent, // 加載失敗時(shí)使用的組件 error: ErrorComponent, // 展示加載時(shí)組件的延時(shí)時(shí)間。默認(rèn)值是 200 (毫秒) delay: 200, // 如果提供了超時(shí)時(shí)間且組件加載也超時(shí)了, // 則使用加載失敗時(shí)使用的組件。默認(rèn)值是:`Infinity` timeout: 3000 })
小結(jié)
本篇我們主要圍繞著Vue組件中的插槽和相關(guān)動(dòng)態(tài)組件、異步組件的內(nèi)容進(jìn)行了梳理。通過這兩篇的整理,我們對(duì)于Vue組件有了一個(gè)比較整體的了解。后續(xù)我們會(huì)在實(shí)戰(zhàn)過程中針對(duì)具體的點(diǎn)再進(jìn)行詳細(xì)的說明。
以上所述是小編給大家介紹的Vue.js組件詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
vue+video.js視頻播放、視頻切換、視頻斷點(diǎn)分段上傳功能
本次需求是做一個(gè)視頻列表,點(diǎn)擊視頻列表播放對(duì)應(yīng)視頻;同時(shí)要求實(shí)現(xiàn)斷點(diǎn)分段上傳大文件(視頻)的功能,今天通過本文給大家講解下vue+video.js視頻播放、視頻切換、視頻斷點(diǎn)分段上傳功能,感興趣的朋友一起看看吧2022-12-12使用webpack手動(dòng)搭建vue項(xiàng)目的步驟
這篇文章主要介紹了從零使用webpack手動(dòng)搭建vue項(xiàng)目的步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03vue quill editor 使用富文本添加上傳音頻功能
vue-quill-editor 是vue項(xiàng)目中常用的富文本插件,其功能能滿足大部分的項(xiàng)目需求。這篇文章主要介紹了vue-quill-editor 富文本添加上傳音頻功能,需要的朋友可以參考下2020-01-01vue使用腳手架vue-cli創(chuàng)建并引入自定義組件
這篇文章介紹了vue使用腳手架vue-cli創(chuàng)建并引入自定義組件的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03vue路由跳轉(zhuǎn)時(shí)判斷用戶是否登錄功能的實(shí)現(xiàn)
下面小編就為大家?guī)硪黄獀ue路由跳轉(zhuǎn)時(shí)判斷用戶是否登錄功能的實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10