目录
- 编写组件细节
- 组件嵌套子组件slot插槽的用法
- 非父子组件间的通信
1. 编写组件细节
你给予组件的名字可能依赖于你打算拿它来做什么。当直接在 DOM 中使用一个组件 (而不是在字符串模板或单文件组件) 的时候,我们强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)。这会帮助你避免和当前以及未来的 HTML 元素相冲突。
定义组件名称的方式有两种:
1.1 使用Kebab-case (短横线分隔命名)
Vue.component('my-component-name',{/* */})
当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如<my-component-name>。
1.2 使用PascalCase (驼峰式命名)
Vue.component('MyComponentName',{/* */})
当使用 PascalCase (驼峰式命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name>和 <MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。
2. 组件嵌套子组件
在某些情况我们是需要使用到嵌套组件,也就是说组件还可以继续嵌套组件。形成嵌套组件有两种的实现方式。
2.1 父组件直接嵌套子组件

<div id="app">
<item-A></item-A>
</div>
<script>
Vue.component('itemA',{
template:'<div>123<itemB></itemB></div>'
})
Vue.component('itemB',{
template:'<div>456</div>'
})
new Vue({
el:'#app'
})
</script>
2.2 父组件通过插槽(slot)嵌套
插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示、以及怎样显示由父组件来决定。
插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。那么插槽(slot)分成3种分别是:单个插槽,具名插槽,作用域插槽。
2.3 单个插槽
首先是单个插槽,单个插槽是vue的官方叫法,但是其实也可以叫它默认插槽,或者与具名插槽相对,我们可以叫它匿名插槽。因为它不用设置name属性。
<div id="app">
<item>
<h4>
Hello Vue
</h4>
</item>
</div>
<script>
Vue.component('item',{
data(){
return {
}
},
template:`
<div>
<slot></slot>
</div>
`
})
</script>
2.4 具名插槽
匿名插槽没有name属性,所以是匿名插槽,那么,插槽加了name属性,就变成了具名插槽。具名插槽可以在一个组件中出现N次,出现在不同的位置。

<div id="app">
<item>
<div class="header" slot="header">
header
</div>
<div class="footer" slot="footer">
footer
</div>
</item>
</div>
<script>
Vue.component('item',{
template:`
<div>
<slot name="header"></slot>
<div class="content">content</div>
<slot name="footer"></slot>
</div>
`
})
new Vue({
el:'#app'
})
</script>
2.5 作用域插槽
作用域插槽是一种特殊类型的插槽,用作一个(能被传递数据的)可重用模板,来代替已经渲染好的元素。
在子组件中,只需将数据传递到插槽,就像你将prop传递给组件一样:
<div id="app">
<item>
<template slot-scope="props">
<li>
{{props.item}}
</li>
</template>
</item>
</div>
<script>
Vue.component('item',{
data(){
return{
list:[1,2,3,4,5]
}
},
template:`
<div>
<ul>
<slot v-for="item in list" :item="item">
</slot>
</ul>
</div>
`
})
new Vue({
el:'#app'
})
</script>