|
27 | 27 | * 功能基本一致 |
28 | 28 | * UI有差距 |
29 | 29 |
|
30 | | -也就是说需要将UI设置成动态的。这个时候就需要用到`slot`(内容分发)。 |
| 30 | +也就是说需要将UI设置成动态的。这个时候就需要用到`slot`(插槽)。 |
31 | 31 |
|
32 | 32 | ## slot |
33 | 33 |
|
|
61 | 61 | </script> |
62 | 62 | ```` |
63 | 63 |
|
| 64 | +slot分为3种类型,第一种是普通插槽,也就是我们上边提到这种写法;第二种是具名插槽,具名插槽也就是在上边的基础上加了一个`name`属性,这种用法主要体现在你在一个组件内部需要很多的插槽,这个时候你需要一个属性值来区分每一个插槽,也方便使用的时候对号入座。还是上边的例子我们加以改写一下: |
| 65 | + |
| 66 | +```html |
| 67 | +<div id="app"> |
| 68 | + <div class="box"> |
| 69 | + <alert></alert> |
| 70 | + </div> |
| 71 | + <div class="box"> |
| 72 | + <alert> |
| 73 | + This is message box with special close icon. |
| 74 | + <span class="close-icon" slot="close">-</span> |
| 75 | + </alert> |
| 76 | + </div> |
| 77 | +</div> |
| 78 | +<script type="text/x-template" id="message"> |
| 79 | + <div class="message" :class="messageClasses"> |
| 80 | + <a class="close" @click="close"> |
| 81 | + <slot name="close">×</slot> |
| 82 | + </a> |
| 83 | + <slot>This is message box!!!</slot> |
| 84 | + </div> |
| 85 | +</script> |
| 86 | +``` |
| 87 | +<iframe height="400" style="width: 100%;" scrolling="no" title="message-box-1" src="//codepen.io/uncleze2017/embed/rEmxvV/?height=265&theme-id=0&default-tab=result" frameborder="no" allowtransparency="true" allowfullscreen="true"> |
| 88 | + See the Pen <a href='https://codepen.io/uncleze2017/pen/rEmxvV/'>message-box-1</a> by uncleze |
| 89 | + (<a href='https://codepen.io/uncleze2017'>@uncleze2017</a>) on <a href='https://codepen.io'>CodePen</a>. |
| 90 | +</iframe> |
| 91 | + |
| 92 | +第三种叫作用用插槽(slot-scope),vue每个组件在渲染的时候会形成一个作用域,每个组件的作用域都是独立的,包括父子这类关系的组件。**slot-scope可以将子组件的内容传递到父组件**。 |
| 93 | + |
| 94 | +通过向子组件中的`<slot>`元素添加一些props,将参数传递给父元素,并且父元素通过将它们从特殊的slot-scope属性解构来访问这些参数。 |
| 95 | + |
| 96 | +上边案例中,close-icon这个关闭按钮的事件函数是绑定在close这个元素上边,而且是在组件内部绑定的。刚才我们实现了close-icon的替换,假如UI这边需要调整close-icon的位置,最快的方法是改样式,改样式首先需要考虑这个组件大概那些地方会用到,是全局改样式还是只是改局部的,如果不是使用第三方组件的情况下,也就是咱们从开发一个组件的方面考虑,适应常用场景下保证组件灵活性,避免使用者使用的时候需要对组件内部进行修改。所以我们这里使用slot-scope来对上边的案例进行一个修改。 |
| 97 | + |
| 98 | +<iframe height="265" style="width: 100%;" scrolling="no" title="message-box-2" src="//codepen.io/uncleze2017/embed/ewWZGv/?height=265&theme-id=0&default-tab=result" frameborder="no" allowtransparency="true" allowfullscreen="true"> |
| 99 | + See the Pen <a href='https://codepen.io/uncleze2017/pen/ewWZGv/'>message-box-2</a> by uncleze |
| 100 | + (<a href='https://codepen.io/uncleze2017'>@uncleze2017</a>) on <a href='https://codepen.io'>CodePen</a>. |
| 101 | +</iframe> |
| 102 | + |
| 103 | +```html |
| 104 | +<div id="app"> |
| 105 | + <div class="box"> |
| 106 | + <alert></alert> |
| 107 | + </div> |
| 108 | + <div class="box"> |
| 109 | + <alert hide-close> |
| 110 | + <template slot-scope="{close}"> |
| 111 | + Box with special close icon. |
| 112 | + <span class="close-icon" @click="close">×</span> |
| 113 | + </template> |
| 114 | + </alert> |
| 115 | + </div> |
| 116 | +</div> |
| 117 | +<script type="text/x-template" id="message"> |
| 118 | + <div class="message" v-show="isShow" :class="messageClasses"> |
| 119 | + <a class="close" @click="close" v-if="!hideClose"> |
| 120 | + <slot name="close">×</slot> |
| 121 | + </a> |
| 122 | + <slot :close="close">This is message box!!!</slot> |
| 123 | + </div> |
| 124 | +</script> |
| 125 | +``` |
| 126 | +将close这个方法用slot-scope传递到了父组件,让使用这可以自定义元素并绑定事件函数,解决之前只能在内部固定绑定事件的情况。 |
| 127 | + |
| 128 | +## 行为与表象分离 |
| 129 | + |
| 130 | +我们通过slot和slot-scope给使用这提供部分自定义html和调用自己内部实现的函数的途径。让使用者自定义部分html,然后还能方便的调用函数,并且不用理会内部的状态。 |
| 131 | + |
| 132 | +其实我们仔细想想,就上述的组件,其实完全可以让用户自定义全部的html,也就是组件不渲染html,只提供函数,和组件的状态。 |
| 133 | + |
0 commit comments