本章开始介绍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配置项是用来传入够短的配置项。
你们能够在这里看到源码。