今天小編給大家分享一下Vue中的插槽、內(nèi)容分發(fā)、具名插槽應(yīng)用實(shí)例分析的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
創(chuàng)新互聯(lián)長(zhǎng)期為近1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為博野企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè),博野網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
Vue中組件的數(shù)據(jù)可以通過props進(jìn)行傳遞,或者通過事件的方式進(jìn)行獲取傳遞,但當(dāng)需要接收模板內(nèi)容(任意合法的模板內(nèi)容,代碼片段、Vue組件)時(shí),就需要使用插槽來實(shí)現(xiàn)了。當(dāng)然也可以通過函數(shù)式編程間接實(shí)現(xiàn)。
可以將插槽理解為js中的函數(shù)進(jìn)行編譯
// 父元素傳入插槽內(nèi)容
FancyButton('Click me!')
// FancyButton 在自己的模板中渲染插槽內(nèi)容
function FancyButton(slotContent) {
return ``
}
最好的封裝方式是將共性抽取到組件中,將不同點(diǎn)暴露為插槽 - 抽取共性,保留不同
父組件模板的所有東西都會(huì)在父組件作用域中編譯,子組件模板的所有東西都會(huì)在子組件作用域內(nèi)編譯 - 編譯作用域
常規(guī)的slot可以用于自定義組件的模板,但只是限制于固定的模板,無法自定義內(nèi)部的具體的某一項(xiàng),即常規(guī)的slot無法實(shí)現(xiàn)對(duì)組件循環(huán)體的每一項(xiàng)進(jìn)行不同的內(nèi)容分發(fā),此時(shí)可以通過slot-scope進(jìn)行實(shí)現(xiàn),本質(zhì)上和slot一樣,不同點(diǎn)在于可以進(jìn)行參數(shù)傳遞
//普通的組件定義
{{ book.name }}
//slot-scope組件定義
{{ book.name }}
//父組件使用
限時(shí)優(yōu)惠
{{ slotProps.book.name }}
使用slot-scope時(shí),當(dāng)父組件使用該API,對(duì)應(yīng)的插槽會(huì)替換模板中的slot進(jìn)行展示
在組件中定義多個(gè)插槽出口可以兼容多個(gè)不同需求的兼容性,使得多個(gè)插槽內(nèi)容傳入到各自的插槽出口中;當(dāng)插槽中配置了
name
屬性時(shí),此插槽就被稱為具名插槽(named slots),沒有提供name的插槽會(huì)隱式命名為「default」
v-slot
可以簡(jiǎn)寫為#
,其值對(duì)應(yīng)于插槽中的name
對(duì)應(yīng)的值;
當(dāng)在一個(gè)組件中同時(shí)存在默認(rèn)插槽和具名插槽時(shí),所有位于頂級(jí)的非template
節(jié)點(diǎn)都被隱式的視為默認(rèn)插槽的內(nèi)容,因此可以省略默認(rèn)插槽的template
節(jié)點(diǎn)標(biāo)簽;
A paragraph for the main content.
And another one.
Here's some contact info
普通的插槽,是無法獲取其他作用域下的數(shù)據(jù)的,即
父組件模板中的表達(dá)式只能訪問父組件的作用域;子組件模板中的表達(dá)式只能訪問子組件的作用域
但在某些情況下,插槽中的內(nèi)容想要同時(shí)使用父組件和子組件內(nèi)的數(shù)據(jù),可以通過像組件傳遞數(shù)據(jù)props
那樣,讓子組件在渲染時(shí)將一部分?jǐn)?shù)據(jù)提供給插槽,這樣在組件外部(父組件)中就可以使用子組件中的數(shù)據(jù)了-通過slot
的方式
子組件傳入插槽的 props 作為了 v-slot
指令的值,可以在插槽內(nèi)的表達(dá)式中訪問,其中name是Vue特意保留的attribute,不會(huì)作為props進(jìn)行傳遞
數(shù)據(jù)傳遞
//子組件
數(shù)據(jù)接收
//父組件 - 使用方
{{ shopInfo }} {{ userInfo }}
{{ shopInfo }}
{{ introduction }}
{{ userInfo }}
具名插槽接收
默認(rèn)插槽接收
使用slot-scope時(shí),用最后一個(gè)slot-scope替換模板中的slot
555
{{scope.name}}
{{scope}}
{{scope.name}}
{{scope.age}}
使用作用域插槽時(shí),可以實(shí)現(xiàn)既可以復(fù)用子組件slot,又可以使得slot的內(nèi)容不一致,它允許使用者傳遞一個(gè)模板而不是已經(jīng)渲染好的元素給插槽,所謂作用域是指模板雖然在父級(jí)作用域中渲染的,但是卻可以拿到子組件的數(shù)據(jù)
常規(guī)的v-bind需要攜帶參數(shù)key值進(jìn)行傳遞,例如v-bind:info = '123'
;但是有時(shí)候會(huì)省略這個(gè)key值,直接進(jìn)行傳遞數(shù)據(jù),如v-bind = 'item'
,這種用法會(huì)將整個(gè)對(duì)象的所有屬性都綁定到當(dāng)前元素上,適用于需要綁定的屬性過多的場(chǎng)景
// data: {
// shapes: [
// { name: 'Square', sides: 4 },
// { name: 'Hexagon', sides: 6 },
// { name: 'Triangle', sides: 3 }
// ],
// colors: [
// { name: 'Yellow', hex: '#F4D03F', },
// { name: 'Green', hex: '#229954' },
// { name: 'Purple', hex: '#9B59B6' }
// ]
// }
{{ shape.name }} ({{ shape.sides }} sides)
{{ color.name }}
{{ title }}
Vue.component('my-list', {
template: '#my-list',
props: [ 'title', 'items' ]
});
遞歸組件就是指組件在模板中調(diào)用自己,由于是組件自身調(diào)用,就不能像常規(guī)組件定義一樣,可以省略組件的name配置,組件的遞歸需要依賴于自身的name配置(name還用于遍歷組件的name選項(xiàng)來查找組件的實(shí)例);
滿足條件
需要給組件設(shè)置一個(gè)name屬性
需要有一個(gè)明確的結(jié)束條件
<= 5">
有時(shí)候我們需要根據(jù)一些條件,動(dòng)態(tài)的切換/選擇某個(gè)組件,在函數(shù)式組件中,沒有上下文的概念,常用于程序化的在多個(gè)組件中選擇一個(gè),可以間接的解決動(dòng)態(tài)切換組件的需求,缺點(diǎn)是基于js對(duì)象進(jìn)行開發(fā),不方便開發(fā);
Vue官方提供了一個(gè)內(nèi)置組件和is的屬性,用來解決上述的問題
//component 就是js import進(jìn)的組件實(shí)例,其值可以是標(biāo)簽名、組件名、直接綁定一個(gè)對(duì)象等
為了使得組件具有緩存作用,可以使用的內(nèi)置組件,這樣只要不離開當(dāng)前頁(yè)面,切換到其他組件后deforeDestory不會(huì)執(zhí)行,因此組件具有了緩存功能
常規(guī)的組件components是直接通過引用定義好的組件進(jìn)行展示的,也可以直接在當(dāng)前組件內(nèi)定義,然后通過配置components進(jìn)行渲染
Lbxin
class - 11
簡(jiǎn)介HTML的slot元素,是Web Components技術(shù)套件的一部分,是Web組件內(nèi)的一個(gè)占位符,該占位符可以在后期使用自己的標(biāo)記語(yǔ)言進(jìn)行填充,這樣可以創(chuàng)建單獨(dú)的DOM樹,并將其與其他的組件組合在一起 -- MDN
常見的填充Web組件的shadow DOM的模板有template和slot
模板 - Templates
My paragraph
let template = document.getElementById('my-paragraph');
let templateContent = template.content;
document.body.appendChild(templateContent);
customElements.define('my-paragraph',
class extends HTMLElement {
constructor() {
super();
let template = document.getElementById('my-paragraph');
let templateContent = template.content;
const shadowRoot = this.attachShadow({mode: 'open'})
.appendChild(templateContent.cloneNode(true));
}
})
// 自定義標(biāo)簽使用
后續(xù)的樣式邏輯也需要加在template中,方便通過后續(xù)的相關(guān)邏輯(如template.content
獲取到然后打入到指定的容器中)
可以配合Web Component一起使用,實(shí)現(xiàn)純js自定義的組件
需要在網(wǎng)頁(yè)上重復(fù)的使用相同的標(biāo)記結(jié)構(gòu)時(shí),為了避免CV的操作可以通過模板的方式進(jìn)行實(shí)現(xiàn)
需要注意的是模板 - Template 和其內(nèi)部的內(nèi)容是不會(huì)在DOM中呈現(xiàn)的,可以通過js進(jìn)行訪問并添加到DOM中,從而在界面上進(jìn)行展示
Web Component簡(jiǎn)介
類型一:Autonomous custom elements
是獨(dú)立的元素,它不繼承其他內(nèi)建的 HTML 元素,可以直接通過標(biāo)簽的方式進(jìn)行HTML使用
,也可以通過js的方式進(jìn)行使用document.createElement("popup-info")
類型二:Customized built-in elements
繼承自基本的 HTML 元素。在創(chuàng)建時(shí),你必須指定所需擴(kuò)展的元素,使用時(shí),需要先寫出基本的元素標(biāo)簽,并通過 is
屬性指定 custom element 的名稱;或
document.createElement("p", { is: "word-count" })
參數(shù)一:表明創(chuàng)建元素的名稱,其注冊(cè)的名稱不能簡(jiǎn)單的單詞,需要由短劃線進(jìn)行拼接
參數(shù)二:用于定義元素行為的類
參數(shù)三:一個(gè)包含extends屬性配置的配置對(duì)象,可選,指定了所創(chuàng)建的自定義元素是繼承于哪個(gè)內(nèi)置的元素,可以繼承任何內(nèi)置的元素;
customElements.define(
'word-count',
WordCount,
{ extends: 'p' }
);
可以使用ES2015的類實(shí)現(xiàn)
class WordCount extends HTMLParagraphElement {
constructor() {
// 必須首先調(diào)用 super 方法
super();
// 元素的功能代碼寫在這里
...
}
}
Web Component的一個(gè)很重要的屬性就是封裝 - 可以將標(biāo)記結(jié)構(gòu)、樣式和行為影藏起來,并于界面上的其他代碼隔離開來,保證代碼的獨(dú)立性
Web Component標(biāo)準(zhǔn)非常重要的一個(gè)特性是,使得開發(fā)者可以將HTML頁(yè)面的功能封住成custom elements(自定義標(biāo)簽)
customElements 接口用來實(shí)現(xiàn)一個(gè)對(duì)象,允許開發(fā)者注冊(cè)一個(gè)custom elements的信息,返回已注冊(cè)的自定義標(biāo)簽的信息;
customElements.define方法用來注冊(cè)一個(gè)custom element,接收三個(gè)參數(shù)
自定義標(biāo)簽的類型
參考文獻(xiàn) - MDN
shadow DOM簡(jiǎn)介
shadow DOM主要是將一個(gè)隱藏的、獨(dú)立的DOM樹附加到常規(guī)的DOM樹上,是以shadow DOM節(jié)點(diǎn)為起始根節(jié)點(diǎn),在這個(gè)根節(jié)點(diǎn)的下方,可以是任意的元素,和普通的DOM元素一致
Shadow host:一個(gè)常規(guī) DOM 節(jié)點(diǎn),Shadow DOM 會(huì)被附加到這個(gè)節(jié)點(diǎn)上。
Shadow tree:Shadow DOM 內(nèi)部的 DOM 樹。
Shadow boundary:Shadow DOM 結(jié)束的地方,也是常規(guī) DOM 開始的地方。
Shadow root: Shadow tree 的根節(jié)點(diǎn)。
圖解Shandow DOM
如常見的video標(biāo)簽,其內(nèi)部的一些控制器和按鈕等都是通過Shandow DOM進(jìn)行維護(hù)的,開發(fā)者可以通過這個(gè)API進(jìn)行自己獨(dú)立的邏輯控制
基本用法
let shadow1 = elementRef.attachShadow({mode: 'open'});
let shadow2 = elementRef.attachShadow({mode: 'closed'});
let myShadowDom = shadow1.shadowRoot; // 具體內(nèi)容
let myShadowDom = shadow2.shadowRoot; //null
let shadow = this.attachShadow({mode: 'open'});
// 將一個(gè)shadow DOM添加到一個(gè)元素上之后就可以使用DOM API進(jìn)行操作訪問了
當(dāng)需要將一個(gè)shadow DOM添加到自定義的標(biāo)簽上時(shí),可以在自定義的構(gòu)造函數(shù)中添加如下邏輯;
Element.attachShadow()方法可以將一個(gè)shadow DOM添加到任何一個(gè)元素上,接收一個(gè)配置對(duì)象參數(shù),該對(duì)象有一個(gè)mode
的屬性,值可以是open - 可以通過外部js獲取 Shadow DOM和closed - 外部不可以通過js進(jìn)行獲取 Shadow DOM
以上就是“Vue中的插槽、內(nèi)容分發(fā)、具名插槽應(yīng)用實(shí)例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。