本章開始介紹slot機制。javascript
slot是WEBComponent引進的東西,叫作插槽。在瀏覽器中,它爲一個content元素。不過有資料代表,它會改名爲slot。 而且在其餘語言的模板引擎中,slot標籤更爲經常使用。所以avalon2的組件機制使用slot元素。html
但說了這麼久,slot元素究竟是什麼鬼?slot是一個佔位符。它有一個name屬性。假如另外一個地方,也有一個元素,它帶一個slot屬性,當這兩個屬性值一致,那麼那個元素就會 挪過來,替換掉這個slot元素。java
<p id="eee"><slot name="aaa">這是插槽元素,這裏面的內容是什麼也無關</slot></p> <p id="kkk"><span slot="aaa">這是要移動的元素</span></p>
最後會轉換爲git
<p id="eee"><span slot="aaa">這是要移動的元素</span></p> <p id="kkk"></p>
是否是很神奇呢?可是這不是全部瀏覽器都支持。avalon2 使用了一些魔術讓IE6也支持slot。github
爲了方便咱們下面的講解。咱們須要引入更多概念。瀏覽器
slot標籤元素: 插槽元素, 用來佔位,就是咱們上學時,用一本書放在某個座位上佔着位置。
帶slot屬性的元素: 插卡元素,用來替換同名的插槽元素。this
而後到咱們的組件,咱們使用wbr, xmp, template, ms-*等元素來聲明它們是某種組件,它們稱之爲組件容器(全部帶ms-widget屬性的元素都是插槽元素)。它們與插槽元素同樣,是用來佔位與被替換掉的。spa
<div ms-controller='widget1' > <xmp :widget="{is:'ms-button'}" ><span slot="content">button!</span></xmp> <p><button :click="@click">click</button></p> </div>
那麼組件容器是被誰替換呢?固然是組件。咱們使用avalon.component來定義組件時,必須有一個template屬性,它是一個HTML模塊,它會轉換爲組件。好比說上面的ms-button.code
avalon.component('ms-button', { template: '<button type="button"><slot name="content" /></button>', defaults: { } })
template裏面有slot元素來佔位,而組件容器裏面有帶slot屬性的元素來替換。component
一個組件能夠擁有N個slot元素,它們的name值不能重複。可是外面的插卡元素則能夠重複。
avalon.component('ms-tabs', { template: '<div><p>它有{{@num}}個面板</p><slot name="tab"/></div>', defaults: { num: 3 } }) vm = avalon.define({ $id: 'widget1' })
<div ms-controller='widget1' > <xmp :widget="{is:'ms-tabs'}"> <div slot="tab">面板1</div> <hr> <div slot="tab">面板2</div> <hr> <div slot="tab">面板3</div> <hr> </xmp> </div>
生成的結構以下:
這也是咱們作切換卡的基礎。好了,咱們看一下切換卡是如何作的。
DOCTYPE html> <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src='../../dist/avalon.js'></script> <script> function heredoc(fn) { return fn.toString().replace(/^[^\/]+\/\*!?\s?/, ''). replace(/\*\/[^\/]+$/, '').trim().replace(/>\s*</g, '><') } avalon.component('ms-tabs', { template: heredoc(function () { /* <div> <div><slot name="btn"/></div> <div><slot name="tab"/></div> </div> */ }), defaults: { buttons: [], tabs: [], active: function (index) { this.activeIndex = index }, activeIndex: 0, } }) var vm = avalon.define({ $id: 'widget1', buttons: [111, 222, 333], aa: '動態內容', ddd: function () { console.log('xxxx') }, change: function () { vm.aa = '更新內容'+(new Date -0) } }) </script> </head> <body> <h1>slot的使用</h1> <p>對slot元素使用循環綁定生成大量元素,一塊兒遷進組件內部</p> <div ms-controller='widget1' > <xmp :widget="{is:'ms-tabs',buttons: @buttons}"> <button ms-for='(index,button) in @buttons' ms-click='@active(index)' type='button' slot='btn' >{{button}}</button> <div slot="tab" ms-visible="0 == @activeIndex"> <p>這是面板1</p> </div> <div slot="tab" ms-visible="1 == @activeIndex"> {{@aa}} <button ms-click="@change" type="button">change</button> </div> <div slot="tab" ms-visible="2 == @activeIndex"> 這是面板3 </div> </xmp> </div> </body> </html>
切換卡包含兩大塊內容,上面用來切換的按鈕,及下面的用來顯示的面板。因爲每次只顯示一個面板,咱們須要使用ms-visible來作隱藏。
最後生成的切換卡是這樣的。
咱們能夠下這樣的結論。slot用來爲組件傳入大片內容的, ms-widget配置項是用來傳入夠短的配置項。
你們能夠在這裏看到源碼。